diff -pruN 7.4.0-3/.gitignore 8.1.0+git2025070715.9d3a956a-0ubuntu2/.gitignore
--- 7.4.0-3/.gitignore	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/.gitignore	1970-01-01 00:00:00.000000000 +0000
@@ -1,26 +0,0 @@
-*.DS_Store
-*.egg*
-*.log
-*.mo
-*.pyc
-*.swo
-*.swp
-*~
-.coverage
-.idea
-.stestr/
-.testrepository
-.tox
-AUTHORS
-build
-ChangeLog
-dist
-# Doc related
-doc/build
-doc/source/contributor/api/
-# Development environment files
-.project
-.pydevproject
-cover
-# Files created by releasenotes build
-releasenotes/build
diff -pruN 7.4.0-3/.gitreview 8.1.0+git2025070715.9d3a956a-0ubuntu2/.gitreview
--- 7.4.0-3/.gitreview	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/.gitreview	1970-01-01 00:00:00.000000000 +0000
@@ -1,4 +0,0 @@
-[gerrit]
-host=review.opendev.org
-port=29418
-project=openstack/python-openstackclient.git
diff -pruN 7.4.0-3/.pre-commit-config.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/.pre-commit-config.yaml
--- 7.4.0-3/.pre-commit-config.yaml	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/.pre-commit-config.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -1,7 +1,7 @@
 ---
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.6.0
+    rev: v5.0.0
     hooks:
       - id: trailing-whitespace
       - id: mixed-line-ending
@@ -15,7 +15,7 @@ repos:
         files: .*\.(yaml|yml)$
         args: ['--unsafe']
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.6.2
+    rev: v0.11.8
     hooks:
       - id: ruff
         args: ['--fix', '--unsafe-fixes']
@@ -26,3 +26,16 @@ repos:
       - id: hacking
         additional_dependencies: []
         exclude: '^(doc|releasenotes)/.*$'
+  - repo: https://github.com/pre-commit/mirrors-mypy
+    rev: v1.15.0
+    hooks:
+      - id: mypy
+        additional_dependencies:
+          - types-requests
+        # keep this in-sync with '[mypy] exclude' in 'setup.cfg'
+        exclude: |
+          (?x)(
+            doc/.*
+            | examples/.*
+            | releasenotes/.*
+          )
diff -pruN 7.4.0-3/.zuul.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/.zuul.yaml
--- 7.4.0-3/.zuul.yaml	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/.zuul.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -23,8 +23,8 @@
       zuul_work_dir: src/opendev.org/openstack/python-openstackclient
 
 - job:
-    name: osc-tox-py39-tips
-    parent: openstack-tox-py39
+    name: osc-tox-py310-tips
+    parent: openstack-tox-py310
     description: |
       Run unit tests for OpenStackClient with master branch of important libs.
 
@@ -43,8 +43,8 @@
       zuul_work_dir: src/opendev.org/openstack/python-openstackclient
 
 - job:
-    name: osc-tox-py312-tips
-    parent: openstack-tox-py312
+    name: osc-tox-py313-tips
+    parent: openstack-tox-py313
     description: |
       Run unit tests for OpenStackClient with master branch of important libs.
 
@@ -137,22 +137,6 @@
       tox_envlist: functional
       tox_install_siblings: true
 
-- secret:
-    name: osc-dockerhub
-    data:
-      username: osclientzuul
-      password: !encrypted/pkcs1-oaep
-        - LbIZjJiVstRVXMpoLQ3+/JcNB6lKVUWJXXo5+Outf+PKAaO7mNnv8XLiFMKnJ6ftopLyu
-          hWbX9rA+NddvplLQkf1xxkh7QBBU8PToLr58quI2SENUclt4tpjxbZfZu451kFSNJvNvR
-          E58cHHpfJZpyRnS2htXmN/Qy24gbV2w7CQxSZD2YhlcrerD8uQ8rWEnlY1wcJEaEGomtS
-          ZTGxsdK2TsZC2cd4b7TG7+xbl2i+hjADzwSQAgUzlLlwuG71667+IWk4SOZ7OycJTv9NN
-          ZTak8+CGfiMKdmsxZ1Z8uD7DC+RIklDjMWyly6zuhWzfhOmsmU0CesR50moodRUvbK79p
-          NZM8u0hBex5cl2EpUEwJL/FSPJXUhDMPoMoTZT/SAuXf25R9eZ9JGrKsIAlmVhpl8ifoE
-          8TpPyvIHGS3YelTQjhqOX0wGb9T4ZauQCcI5Ajzy9NuCTyD9xxme9OX1zz7gMACRnVHvz
-          q7U7Ue90MnmGH6E2SgKjIZhyzy9Efwb7JUvH1Zb3hlrjCjEhwi9MV5FnABTEeXyYwE10s
-          3o/KZg2zvdWkVG6x0dEkjpoQaNuaB7T2Na7Sm421n/z3LCzhiQGuTUjENnL6cMEtuA6Pp
-          BfI5+Qlg7HMwkBXNB73EPfWHzbCR3VNrzGYTy9FvhGud0/cXsuBXgps4WH63ic=
-
 - job:
     name: osc-build-image
     parent: opendev-build-docker-image
@@ -162,49 +146,21 @@
       - python-builder-3.11-bookworm-container-image
       - python-base-3.11-bookworm-container-image
     provides: osc-container-image
-    vars: &osc_image_vars
+    vars:
       docker_images:
         - context: .
-          repository: osclient/python-openstackclient
-
-- job:
-    name: osc-upload-image
-    parent: opendev-upload-docker-image
-    description: Build Docker images and upload to Docker Hub.
-    allowed-projects: openstack/python-openstackclient
-    requires:
-      - python-builder-3.11-bookworm-container-image
-      - python-base-3.11-bookworm-container-image
-    provides: osc-container-image
-    secrets:
-      - name: docker_credentials
-        secret: osc-dockerhub
-        pass-to-parent: true
-    vars: *osc_image_vars
-
-- job:
-    name: osc-promote-image
-    parent: opendev-promote-docker-image
-    allowed-projects: openstack/python-openstackclient
-    description: Promote previously uploaded Docker images.
-    secrets:
-      - name: docker_credentials
-        secret: osc-dockerhub
-        pass-to-parent: true
-    nodeset:
-      nodes: []
-    vars: *osc_image_vars
+          tags: []
 
 - project-template:
     name: osc-tox-unit-tips
     check:
       jobs:
-        - osc-tox-py39-tips
-        - osc-tox-py312-tips
+        - osc-tox-py310-tips
+        - osc-tox-py313-tips
     gate:
       jobs:
-        - osc-tox-py39-tips
-        - osc-tox-py312-tips
+        - osc-tox-py310-tips
+        - osc-tox-py313-tips
 
 - project:
     templates:
@@ -217,7 +173,8 @@
       - release-notes-jobs-python3
     check:
       jobs:
-        - osc-build-image
+        - osc-build-image:
+            voting: false
         - osc-functional-devstack
         - osc-functional-devstack-tips:
             # The functional-tips job only tests the latest and shouldn't be run
@@ -225,8 +182,4 @@
             branches: ^master$
     gate:
       jobs:
-        - osc-upload-image
         - osc-functional-devstack
-    promote:
-      jobs:
-        - osc-promote-image
diff -pruN 7.4.0-3/AUTHORS 8.1.0+git2025070715.9d3a956a-0ubuntu2/AUTHORS
--- 7.4.0-3/AUTHORS	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/AUTHORS	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1,592 @@
+0weng <oweng@osuosl.org>
+Aaron Rosen <aaronorosen@gmail.com>
+Abhishek Chanda <abhishek@cloudscaling.com>
+Abhishek Raut <rauta@vmware.com>
+Adam Harwell <flux.adam@gmail.com>
+Adam Spiers <aspiers@suse.com>
+Adriano Fialho <dritec@gmail.com>
+Akihiro Motoki <amotoki@gmail.com>
+Akihiro Motoki <motoki@da.jp.nec.com>
+Alan Bishop <abishop@redhat.com>
+Alessandro Pilotti <ap@pilotti.it>
+Alessio Ababilov <aababilo@yahoo-inc.com>
+Alessio Ababilov <aababilov@griddynamics.com>
+Alex Gaynor <alex.gaynor@gmail.com>
+Alex Holden <alex@alexjonasholden.com>
+Alex Katz <akatz@akatz.tlv.csb>
+Alex Schultz <aschultz@mirantis.com>
+Alexander Gräb <alexander.graeb@secustack.com>
+Alexander Ignatov <aignatov@mirantis.com>
+Alfredo Moralejo <amoralej@redhat.com>
+Allain Legacy <Allain.legacy@windriver.com>
+Alvaro Lopez Garcia <aloga@ifca.unican.es>
+Amey Bhide <abhide@vmware.com>
+Andreas Florath <Andreas.Florath@telekom.de>
+Andreas Jaeger <aj@suse.com>
+Andreas Jaeger <aj@suse.de>
+Andrey Kurilin <akurilin@mirantis.com>
+Andrey Larionov <anlarionov@gmail.com>
+Anh Tran <anhtt@vn.fujitsu.com>
+Anindita Das <anindita.das@intel.com>
+Anita Kuno <anteaya@anteaya.info>
+Ankur Gupta <ankur.gupta@intel.com>
+Anne Gentle <agentle@cisco.com>
+Anton Frolov <af9740@att.com>
+Antonia Gaete <antoniagaete@osuosl.org>
+Aradhana Singh <aradhana1.singh>
+Areg Grigoryan <argrigor@cern.ch>
+Ariel-Berkowicz <arielmb@bu.edu>
+Artem Goncharov <Artem.goncharov@gmail.com>
+Artem Goncharov <artem.goncharov@gmail.com>
+ArtofBugs <oweng@osuosl.org>
+Artom Lifshitz <alifshit@redhat.com>
+Asha Saravanamohan <assarava@cisco.com>
+Ashish Singh <ashish.singh7@tcs.com>
+Atsushi SAKAI <sakaia@jp.fujitsu.com>
+Badhmapriya Boopalan <Badhmapriya.Boopalan@cognizant.com>
+Ben Andrews <andrewsben@gmail.com>
+Bence Romsics <bence.romsics@ericsson.com>
+Bence Romsics <bence.romsics@gmail.com>
+Benoît Knecht <benoit.knecht@fsfe.org>
+Bernard Cafarelli <bcafarel@redhat.com>
+Bharat Kunwar <bharat@stackhpc.com>
+Bhuvan Arumugam <bhuvan@apache.org>
+Bin Zhou <zhou.bin9@zte.com.cn>
+Boris Bobrov <bbobrov@mirantis.com>
+Boris Pavlovic <boris@pavlovic.me>
+Brad Behle <behle@us.ibm.com>
+Bram Verschueren <verschueren.bram@gmail.com>
+Brandon Palm <bapalm@us.ibm.com>
+Brian Haley <bhaley@redhat.com>
+Brian Haley <brian.haley@hpe.com>
+Brian Haley <haleyb.dev@gmail.com>
+Brian Rosmaita <brian.rosmaita@rackspace.com>
+Brian Rosmaita <rosmaita.fossdev@gmail.com>
+Brianna Poulos <Brianna.Poulos@jhuapl.edu>
+Cao Xuan Hoang <hoangcx@vn.fujitsu.com>
+Carl Baldwin <carl@ecbaldwin.net>
+Carlos Goncalves <carlos.goncalves@neclab.eu>
+Carlos Konstanski <ckonstanski@pippiandcarlos.com>
+Cedric Brandily <zzelle@gmail.com>
+Chaemin-Lim <antraxmin@naver.com>
+Chaozhe.Chen <chaozhe.chen@easystack.cn>
+Chen <dstbtgagt@foxmail.com>
+Chen Hanxiao <chenhx@certusnet.com.cn>
+Chengen Du <chengen.du@canonical.com>
+Choe, Cheng-Dae <whitekid@gmail.com>
+Chris Johnson <wchrisjohnson@gmail.com>
+Christian Berendt <berendt@b1-systems.de>
+Christian Rohmann <christian.rohmann@inovex.de>
+Christian Schneemann <schneemann@b1-systems.de>
+Chuck Short <chuck.short@canonical.com>
+Clark Boylan <clark.boylan@gmail.com>
+Colleen Murphy <colleen.murphy@suse.com>
+Colleen Murphy <colleen.murphy@suse.de>
+Colleen Murphy <colleen@gazlene.net>
+Colleen Murphy <colleen@puppetlabs.com>
+Colleen Murphy <comurphy@suse.com>
+Corey Bryant <corey.bryant@canonical.com>
+Cyril Roelandt <cyril.roelandt@enovance.com>
+Cyril Roelandt <cyril@redhat.com>
+Dag Stenstad <dag@stenstad.net>
+Daisuke Fujita <fuzita.daisuke@jp.fujitsu.com>
+Daniel Bengtsson <dbengt@redhat.com>
+Daniel Gonzalez <daniel@gonzalez-nothnagel.de>
+Daniel Speichert <Daniel_Speichert@comcast.com>
+Daniel Speichert <daniel@speichert.pl>
+Daniel Strong <dstrong@glyx.co.uk>
+Daniel Wilson <danielcw@bu.edu>
+Dao Cong Tien <tiendc@vn.fujitsu.com>
+Davanum Srinivas <davanum@gmail.com>
+Dave Chen <wei.d.chen@intel.com>
+David Caro <me@dcaro.es>
+David Moreau Simard <dms@redhat.com>
+David Moreau Simard <dmsimard@iweb.com>
+David Rabel <rabel@b1-systems.de>
+David Rosales <darosale@us.ibm.com>
+Dean Troyer <dtroyer@gmail.com>
+Dina Belova <dbelova@mirantis.com>
+Dirk Mueller <dirk@dmllr.de>
+Diwei Zhu <zhu.diw@northeastern.edu>
+Dmitrii Shcherbakov <dmitrii.shcherbakov@canonical.com>
+Dmitriy Chubinidze <dcu995@gmail.com>
+Dmitriy Rabotyagov <drabotyagov@vexxhost.com>
+Dmitriy Rabotyagov <noonedeadpunk@ya.ru>
+Dmitry Tantsur <dtantsur@protonmail.com>
+Dolph Mathews <dolph.mathews@gmail.com>
+Dongcan Ye <hellochosen@gmail.com>
+Doug Goldstein <cardoe@cardoe.com>
+Doug Hellmann <doug.hellmann@dreamhost.com>
+Doug Hellmann <doug@doughellmann.com>
+Doug Wiegley <dwiegley@salesforce.com>
+Dougal Matthews <dougal@redhat.com>
+Douglas Mendizábal <dmendiza@redhat.com>
+Douglas Viroel <viroel@gmail.com>
+Dr. Jens Harbott <harbott@osism.tech>
+Einst Crazy <yu.changcai@99cloud.net>
+Elena Ezhova <eezhova@mirantis.com>
+Elod Illes <elod.illes@est.tech>
+Emilien Macchi <emilien@redhat.com>
+Eric Brown <browne@vmware.com>
+Eric Fried <openstack@fried.cc>
+Fan Zhang <zh.f@outlook.com>
+Fang Zhen <zhen.fang@easystack.cn>
+Fei Long Wang <flwang@catalyst.net.nz>
+Felix Yan <felixonmars@archlinux.org>
+Fernando Royo <froyo@redhat.com>
+Flavio Percoco <flaper87@gmail.com>
+Florent Flament <florent.flament-ext@cloudwatt.com>
+Florian Streibelt <florian.streibelt@sap.com>
+Frode Nordahl <frode.nordahl@canonical.com>
+Gabriel Ramirez <gabrielramirez1109@gmail.com>
+Gage Hugo <gagehugo@gmail.com>
+Gary Kotton <gkotton@vmware.com>
+Georgina Shippey <georgina.shippey@bbc.co.uk>
+Ghanshyam Mann <gmann@ghanshyammann.com>
+Ghe Rivero <ghe.rivero@hp.com>
+Gilles Dubreuil <gilles@redhat.com>
+Glenn Van de Water <glenn.van_de_water@nuagenetworks.net>
+Guang Yee <guang.yee@hpe.com>
+Guang Yee <guang.yee@suse.com>
+Guojian Shao <guojian@unitedstack.com>
+Guoqiang Ding <dingguoqiang@cloudin.cn>
+Gábor Antal <antal@inf.u-szeged.hu>
+Ha Van Tu <tuhv@vn.fujitsu.com>
+Hang Yang <hangyang@verizonmedia.com>
+Hangdong Zhang <hdzhang@fiberhome.com>
+Harald Jensas <hjensas@redhat.com>
+Harry Rybacki <hrybacki@redhat.com>
+Harsh Mutha <hmutha31@bu.edu>
+He Jie Xu <hejie.xu@intel.com>
+Henry Nash <henryn@linux.vnet.ibm.com>
+Hidekazu Nakamura <hid-nakamura@vf.jp.nec.com>
+Hideki Saito <saito@fgrep.org>
+Hieu LE <hieulq@vn.fujitsu.com>
+Hironori Shiina <shiina.hironori@jp.fujitsu.com>
+Hong Hui Xiao <honghui_xiao@yeah.net>
+Hongbin Lu <hongbin.lu@huawei.com>
+Hongbin Lu <hongbin034@gmail.com>
+Honza Pokorny <honza@redhat.com>
+Huan Xiong <huan.xiong@hxt-semitech.com>
+Huang Cheng <huang.cheng@h3c.com>
+Huanxuan Ao <huanxuan.ao@easystack.cn>
+Huda Irshad <hudai@bu.edu>
+Hugh Saunders <hugh@wherenow.org>
+Ian Wienand <iwienand@redhat.com>
+Igor Malinovskiy <u.glide@gmail.com>
+Igor_Bolotin <Igor_Bolotin@symantec.com>
+Igor_Bolotin <igor_bolotin@symantec.com>
+Ilya Persky <ipersky@yahoo-inc.com>
+Ilya Popov <ilya_p@hotmail.com>
+Imtiaz Chowdhury <imtiaz.chowdhury@workday.com>
+Inessa Vasilevskaya <ivasilevskaya@mirantis.com>
+Iswarya_Vakati <v.iswarya@nectechnologies.in>
+Ivan Anfimov <lazekteam@gmail.com>
+Ivan Kolodyazhny <e0ne@e0ne.info>
+JAE YONG LEE <jaeljy135@gmail.com>
+JIHOJU <jihoju96@gmail.com>
+JP Parkin <jpparkin@ca.ibm.com>
+Jackie Yuan <yj2311@126.com>
+Jadon Naas <jadon.naas@canonical.com>
+Jake Yip <jake.yip@ardc.edu.au>
+Jake Yip <jake.yip@unimelb.edu.au>
+James Black <jamesjordanblack604@gmail.com>
+James Denton <james.denton@rackspace.com>
+James E. Blair <jeblair@hp.com>
+James E. Blair <jeblair@redhat.com>
+Jamie Lennox <jamielennox@redhat.com>
+Jan Gutter <jan.gutter@netronome.com>
+Jan Hartkopf <jhartkopf@inovex.de>
+Jan Ueberacker <jan.ueberacker@inovex.de>
+Jas <singhj@us.ibm.com>
+Jaspreet Singh Rawel <jaspreetsinghrawel@gmail.com>
+Javier Pena <jpena@redhat.com>
+Jean-Philippe Evrard <jean-philippe@evrard.me>
+Jens Harbott (frickler) <j.harbott@x-ion.de>
+Jens Harbott <j.harbott@x-ion.de>
+Jens Rosenboom <j.rosenboom@x-ion.de>
+Jeremy Houser <jh629g@att.com>
+Jeremy Liu <liujiong@gohighsec.com>
+Jeremy Stanley <fungi@yuggoth.org>
+Jerry George <jerry@ca.ibm.com>
+Jieon Lee <dlwldjs7544@naver.com>
+JieonLee <dlwldjs7544@naver.com>
+Jim Rollenhagen <jim@jimrollenhagen.com>
+Jimmy McCrory <jimmy.mccrory@gmail.com>
+JingLiu <liu.jing5@zte.com.cn>
+Jipyo Hong <hongsbien@naver.com>
+Jirayut Nimsaeng <wingth@gmail.com>
+Jiri Podivin <jpodivin@redhat.com>
+Joe Gordon <joe.gordon0@gmail.com>
+Joe Wigglesworth <wiggles@ca.ibm.com>
+Joel Capitao <jcapitao@redhat.com>
+Johannes Kulik <johannes.kulik@sap.com>
+John Dennis <jdennis@redhat.com>
+John Keenleyside <keenley@ca.ibm.com>
+Jordan Pittier <jordan.pittier@scality.com>
+Jose Castro Leon <jose.castro.leon@cern.ch>
+Josephine Seifert <josephine.seifert@secustack.com>
+Josh Kearney <josh.kearney@pistoncloud.com>
+Joshua Harlow <harlowja@yahoo-inc.com>
+Juan Antonio Osorio Robles <juan.osorio.robles@ericsson.com>
+Jude Cross <jucross@blizzard.com>
+Jude Job <judeopenstack@gmail.com>
+Julie Pichon <jpichon@redhat.com>
+Julien Danjou <julien@danjou.info>
+Justin A Wilson <justin.wilson@intel.com>
+KATO Tomoyuki <kato.tomoyuki@jp.fujitsu.com>
+Kailun Qin <kailun.qin@intel.com>
+KeithMnemonic <keith.berger@suse.com>
+Kelvin Lui <kelvinlittle@yahoo.com>
+Ken Thomas <krt@yahoo-inc.com>
+Kendall Nelson <kennelson11@gmail.com>
+Kenneth Chu <chukenne@ca.ibm.com>
+Kevin_Zheng <zhengzhenyu@huawei.com>
+Khomesh Thakre <khomeshthakre24@gmail.com>
+Kristi Nikolla <knikolla@bu.edu>
+Kyrylo Romanenko <kromanenko@mirantis.com>
+LEE JAE YONG <jaeljy135@gmail.com>
+LIU Yulong <i@liuyulong.me>
+Lajos Katona <lajos.katona@ericsson.com>
+Lance Bragstad <lbragstad@gmail.com>
+Lee Yarwood <lyarwood@redhat.com>
+Lewis Denny <ldenny@redhat.com>
+Lin Yang <lin.a.yang@intel.com>
+Lingxian Kong <anlin.kong@gmail.com>
+LiuNanke <nanke.liu@easystack.cn>
+Lorin Hochstein <lorin@nimbisservices.com>
+Lu lei <lei.lu@easystack.cn>
+Léo GEORGEL <leo.georgel@osones.com>
+M V P Nitesh <m.nitesh@nectechnologies.in>
+Maari Tamm <tamm.maari@gmail.com>
+Madhu Mohan Nelemane <mmnelemane@suse.com>
+Major Hayden <major@mhtx.net>
+Maksim Malchuk <maksim.malchuk@gmail.com>
+Manjeet Singh Bhatia <manjeet.s.bhatia@intel.com>
+Manuel Silveyra <silveyra@us.ibm.com>
+Marc Abramowitz <marc@marc-abramowitz.com>
+Marco Fargetta <marco.fargetta@ct.infn.it>
+Marcos Fermin Lobo <marcos.fermin.lobo@cern.ch>
+Marek Aufart <maufart@redhat.com>
+Marek Denis <marek.denis@cern.ch>
+Mark Vanderwiel <vanderwl@us.ibm.com>
+Martin Chlumsky <martin.chlumsky@gmail.com>
+Martin Schuppert <mschuppert@redhat.com>
+Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Masayuki Igawa <masayuki@igawa.io>
+Matt Fischer <matt@mattfischer.com>
+Matt Joyce <matt.joyce@cloudscaling.com>
+Matt Riedemann <mriedem.os@gmail.com>
+Matt Riedemann <mriedem@us.ibm.com>
+Matthew Treinish <mtreinish@kortar.org>
+Matthieu Huin <mhu@enovance.com>
+Michael Gugino <michael.gugino@walmart.com>
+Michael Johnson <johnsomor@gmail.com>
+Michael McCune <msm@redhat.com>
+Michael Still <mikal@stillhq.com>
+Miguel Lavalle <miguel.lavalle@verizonmedia.com>
+Miguel Lavalle <mlavalle@redhat.com>
+Mike Fedosin <mfedosin@redhat.com>
+Mikhail Feoktistov <mfeoktistov@virtuozzo.com>
+Min Min Ren <rminmin@cn.ibm.com>
+Mohammed Al-Dokimi <maldokim@redhat.com>
+Mohammed Naser <mnaser@vexxhost.com>
+Mohan Muppidi <mkumar2301@gmail.com>
+Monty Taylor <mordred@inaugust.com>
+Mouad Benchchaoui <m.benchchaoui@x-ion.de>
+Mridula Joshi <mrjoshi@redhat.com>
+Myeongchul Chae <cocahack@naver.com>
+Nakul Dahiwade <nakul.dahiwade@intel.com>
+Nam Nguyen Hoai <namnh@vn.fujitsu.com>
+Natal Ngétal <hobbestigrou@erakis.eu>
+Nate Johnston <nate.johnston@redhat.com>
+Nathan Kinder <nkinder@redhat.com>
+Navid Pustchi <npustchi@gmail.com>
+Nguyen Phuong An <AnNP@vn.fujitsu.com>
+Nguyen Van Duc <ducnv@vn.fujitsu.com>
+NiallBunting <niall.bunting@hp.com>
+NiallBunting <niall.bunting@hpe.com>
+Nicolas Belouin <nicolas.belouin@gandi.net>
+Nicolas Simonds <nic@metacloud.com>
+Nikita Gerasimov <nikita.gerasimov@oracle.com>
+Nir Magnezi <nmagnezi@redhat.com>
+Noam Angel <noama@mellanox.com>
+Nobuto Murata <nobuto.murata@canonical.com>
+Noorul Islam K M <noorul@noorul.com>
+Nurmatov Mamatisa <nurmatov.mamatisa@huawei.com>
+Oleksii Chuprykov <ochuprykov@mirantis.com>
+Ondřej Nový <ondrej.novy@firma.seznam.cz>
+OpenStack Release Bot <infra-root@openstack.org>
+Paul Belanger <paul.belanger@polybeacon.com>
+Paul Bourke <paul.bourke@oracle.com>
+Pavlo Shchelokovskyy <shchelokovskyy@gmail.com>
+Pedro Martins <phpm13@gmail.com>
+Pedro Navarro <pednape@gmail.com>
+Pete Zaitcev <zaitcev@kotori.zaitcev.us>
+Petr Blaho <pblaho@redhat.com>
+Pierre Hanselmann <pierre.hanselmann@gmail.com>
+Pierre Prinetti <pierreprinetti@redhat.com>
+Pierre Riteau <pierre@stackhpc.com>
+Przemyslaw Szczerbik <przemyslaw.szczerbik@est.tech>
+Qiu Yu <qiuyu@ebaysf.com>
+Radoslaw Smigielski <radoslaw.smigielski@nokia.com>
+Radosław Piliszek <radoslaw.piliszek@gmail.com>
+Radu Mateescu <mateescu@ca.ibm.com>
+Rafael Weingärtner <rafael@apache.org>
+Rajasi Kulkarni <rajasikulkarni18@gmail.com>
+Rajat Dhasmana <rajatdhasmana@gmail.com>
+Rajesh Tailor <ratailor@redhat.com>
+Ramaraja <ramaraja.r@hcl.com>
+Ramaraja Ramachandran <ramaraja.r@hcl.com>
+Reedip <reedip.banerjee@nectechnologies.in>
+Reedip <reedip14@gmail.com>
+René Ribaud <rribaud@redhat.com>
+Richard Theis <rtheis@us.ibm.com>
+Rikimaru Honjo <honjo.rikimaru@po.ntts.co.jp>
+Ritvik Vinodkumar <vinodkumar.r@northeastern.edu>
+Robert Francis <robefran@ca.ibm.com>
+Robin Cernin <rcernin@redhat.com>
+Rodolfo Alonso Hernandez <ralonsoh@redhat.com>
+Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
+Rodrigo Duarte <rodrigods@lsd.ufcg.edu.br>
+Rodrigo Duarte Sousa <rduartes@redhat.com>
+Rodrigo Duarte Sousa <rodrigods@lsd.ufcg.edu.br>
+Roger Luethi <rl@patchworkscience.org>
+Roxana Gherle <roxana.gherle@hp.com>
+Ruby Loo <rloo@oath.com>
+Rudolf Vriend <rudolf.vriend@sap.com>
+Rui Chen <chenrui.momo@gmail.com>
+Rui Yuan Dou <rydou@fiberhome.com>
+Rushi Agrawal <rushi.agr@gmail.com>
+Ryan Selden <ryanx.seldon@intel.com>
+SaiKiran <saikiranveeravarapu@gmail.com>
+Sam Morrison <sorrison@gmail.com>
+SamYaple <sam@yaple.net>
+Sami MAKKI <mail@samimakki.fr>
+Samuel Pilla <sp516w@att.com>
+Samuel de Medeiros Queiroz <samuel@lsd.ufcg.edu.br>
+Samuel de Medeiros Queiroz <samueldmq@gmail.com>
+Sascha Peilicke <saschpe@gmx.de>
+Sascha Peilicke <speilicke@suse.com>
+Sean Dague <sean@dague.net>
+Sean McGinnis <sean.mcginnis@gmail.com>
+Sean Mooney <work@seanmooney.info>
+Sean Perry <sean.perry@hp.com>
+Sean Perry <sean.perry@hpe.com>
+Shane Wang <shane.wang@intel.com>
+Shashank Kumar Shankar <shashank.kumar.shankar@intel.com>
+Sheel Rana <ranasheel2000@gmail.com>
+Shogo Saito <shogo.saito.ac@hco.ntt.co.jp>
+ShogoAdachi <sho-adachi@xc.jp.nec.com>
+Shu Yingya <yingya.shu@easystack.cn>
+Simon Merrick <simonmerrick@catalyst.net.nz>
+Sindhu Devale <sindhu.devale@intel.com>
+Sirushti Murugesan <sirushti.murugesan@hp.com>
+Slawek Kaplonski <skaplons@redhat.com>
+Snow Kim <lilac94.kim@gmail.com>
+SongmingYan <yan.songming@zte.com.cn>
+Stephen Finucane <sfinucan@redhat.com>
+Stephen Finucane <stephen.finucane@intel.com>
+Stephen Finucane <stephen@that.guru>
+Stephen Finucane <stephenfin@redhat.com>
+Steve Martinelli <s.martinelli@gmail.com>
+Steve Martinelli <stevemar@ca.ibm.com>
+Steven Hardy <shardy@redhat.com>
+Stuart McLaren <stuart.mclaren@hp.com>
+Surya Seetharaman <suryaseetharaman.9@gmail.com>
+Sven Wegener <sven.wegener@inovex.de>
+Swapnil Kulkarni (coolsvap) <me@coolsvap.net>
+Sylvain Bauza <sbauza@redhat.com>
+Sławek Kapłoński <slawek@kaplonski.pl>
+Takashi Kajinami <kajinamit@oss.nttdata.com>
+Takashi Kajinami <tkajinam@redhat.com>
+Takashi Natsume <takanattie@gmail.com>
+Tang Chen <chen.tang@easystack.cn>
+Tang Chen <tangchen@cn.fujitsu.com>
+Telles Nobrega <tenobreg@redhat.com>
+Terry Howe <terrylhowe@gmail.com>
+Terry Howe <thowe@hp.com>
+TerryHowe <terrylhowe@gmail.com>
+Thobias Salazar Trevisan <thobiast@gmail.com>
+Thomas Goirand <zigo@debian.org>
+Thrivikram Mudunuri <mthrivikram+opendev@gmail.com>
+Tim Bishop <tim@bishnet.net>
+Tim Burke <tim.burke@gmail.com>
+Tobias Urdin <tobias.urdin@binero.com>
+Tom Cocozzello <tjcocozz@us.ibm.com>
+Tom Jose Kalapura <tomjosekal@gmail.com>
+Tom Stappaerts <tom.stappaerts@nuagenetworks.net>
+Tony Breeds <tony@bakeyournoodle.com>
+Tovin Seven <vinhnt@vn.fujitsu.com>
+Travis Tripp <travis.tripp@hpe.com>
+Trevor McCasland <TM2086@att.com>
+Tuan Do Anh <tuanda@vn.fujitsu.com>
+Tytus Kurek <tytus.kurek@canonical.com>
+Ukesh Kumar Vasudevan <ukeshkumar@gmail.com>
+Valery Tschopp <valery.tschopp@switch.ch>
+Vasyl Saienko <vsaienko@mirantis.com>
+Victor Silva <victsou@gmail.com>
+Vijendra Soni <vijendra.soni@cognizant.com>
+Vincent Legoll <vincent.legoll@idgrilles.fr>
+Violet Kurtz <vi.kurtz@protonmail.com>
+Violet Kurtz <vikurtz@osuosl.org>
+Vishakha Agarwal <agarwalvishakha18@gmail.com>
+Vladimir Eremin <yottatsa@yandex-team.ru>
+Vladimir Kozhukalov <kozhukalov@gmail.com>
+Vu Cong Tuan <tuanvc@vn.fujitsu.com>
+Wenran Xiao <xiaowenran@unitedstack.com>
+Wenzhi Yu <wenzhi_yu@163.com>
+Witold Bedyk <witold.bedyk@est.fujitsu.com>
+Xi Yang <yang.xi@99cloud.net>
+Xiaoyang Zhang <xiaoyang.zhang@easystack.cn>
+YAMAMOTO Takashi <yamamoto@midokura.com>
+Yan Xing'an <yanxingan@cmss.chinamobile.com>
+Yang Hongyang <hongyang.yang@easystack.cn>
+Yang JianFeng <yjf1970231893@gmail.com>
+Yang Youseok <ileixe@gmail.com>
+Yejia Xu <yejia@unitedstack.com>
+Yi Zhao <zhaoyi@cmss.chinamobile.com>
+Yongli He <yongli.he@intel.com>
+YoonSoo LIM <msdbtjd123@naver.com>
+Yoonsoo Lim <msdbtjd123@naver.com>
+Yosef Salmalian <flaslnm@gmail.com>
+Youngjun <yj.yoo@okestro.com>
+YuehuiLei <leiyuehui@inspur.com>
+Yunpeng Li <yunpeng.li@live.cn>
+Zane Bitter <zbitter@redhat.com>
+ZhaoBo <zhaobo6@huawei.com>
+Zhaokun Fu <fuzk@inspur.com>
+Zhenguo Niu <Niu.ZGlinux@gmail.com>
+ZhongShengping <chdzsp@163.com>
+Zhou Zhihong <zhouzhihong@cmss.chinamobile.com>
+adrian-turjak <adriant@catalyst.net.nz>
+asarfaty <asarfaty@vmware.com>
+blue55 <yllan@fiberhome.com>
+caoyuan <cao.yuan@99cloud.net>
+chengkunye <chengkun@unitedstack.com>
+chenxing <chason.chan@foxmail.com>
+chenying <ying.chen@huawei.com>
+choidoa-git <pearl097@naver.com>
+cw0306-lee <us0310306@gmail.com>
+daizhiyong <zhiyong.dai@easystack.cn>
+devMuscle <hongsbien@naver.com>
+djp <dimsss0607@gmail.com>
+dongwenshuai <dong.wenshuai@zte.com.cn>
+elajkat <lajos.katona@est.tech>
+gecong1973 <ge.cong@zte.com.cn>
+gengchc2 <geng.changcai2@zte.com.cn>
+gtema <artem.goncharov@gmail.com>
+guang-yee <guang.yee@hpe.com>
+guangpei.liu <guangpei.liu@easystack.cn>
+guiyanxing <guiyanxing@cmss.chinamobile.com>
+gvrangan <venkatrangang@hcl.com>
+hackertron <jayadityagupta11@gmail.com>
+heesom <heesom.hs@gmail.com>
+heha <zhanghanqun@unitedstack.com>
+henriquetruta <henrique@lsd.ufcg.edu.br>
+hongp <inyong.hong@samsung.com>
+hoosa <janghoosa@gmail.com>
+huangshan <huangshan@fiberhome.com>
+huangtianhua <huangtianhua@huawei.com>
+jay <jayadityagupta11@gmail.com>
+jeckxie <xiexiaozhe@inspur.com>
+ji-xuepeng <ji.xuepeng@zte.com.cn>
+jiahui.qiang <jiahui.qiang@easystack.cn>
+jiangpch <jiangpengcheng@navercorp.com>
+jiaxi <jiaxi@unitedstack.com>
+jichenjc <jichenjc@cn.ibm.com>
+jqjiang.1@gmail.com <jqjiang.1@gmail.com>
+judy-yu <yujie@cmss.chinamobile.com>
+kafka <guowang@unitedstack.com>
+licanwei <li.canwei2@zte.com.cn>
+lihaijing <lihaijing@fiberhome.com>
+likui <likui@yovole.com>
+lin-hua-cheng <os.lcheng@gmail.com>
+lingyongxu <lyxu@fiberhome.com>
+liujunpeng <liujunpeng@inspur.com>
+liusheng <liusheng@huawei.com>
+liuyamin <liuyamin@fiberhome.com>
+liyifeng <307419146@qq.com>
+liyingjun <liyingjun1988@gmail.com>
+lrqrun <lrqrun@gmail.com>
+lsmman <lsmman07@gmail.com>
+lvjiawei <lvjiawei@cmss.chinamobile.com>
+lvxianguo <lvxianguo@inspur.com>
+maaoyu <maaoyu@inspur.com>
+matbu <mat.bultel@gmail.com>
+mb711d <mb711d@att.com>
+melanie witt <melwittt@gmail.com>
+melissaml <ma.lei@99cloud.net>
+mpicea <jjh77745997@gmail.com>
+nidhimittalhada <nidhimittal19@gmail.com>
+niuke <niuke19970315@163.com>
+npraveen35 <npraveen35@gmail.com>
+ohjiwoo <jiwooo.oh@samsung.com>
+okozachenko <okozachenko@vexxhost.com>
+pedh <hcn518@gmail.com>
+pedro <phpm13@gmail.com>
+pengyuesheng <pengyuesheng@gohighsec.com>
+phil-hopkins-a <phil.hopkins@rackspace.com>
+qinchunhua <qin.chunhua@zte.com.cn>
+qingszhao <zhao.daqing@99cloud.net>
+qtang <qtang@vmware.com>
+rabi <ramishra@redhat.com>
+reedip <reedip.banerjee@nectechnologies.in>
+rladntjr4 <rladntjr4@gmail.com>
+root <ranasheel2000@gmail.com>
+ryanKor <equus3144@gmail.com>
+sharat.sharma <sharat.sharma@nectechnologies.in>
+shizhihui <zhihui.shi@easystack.cn>
+songminglong <songminglong@cmss.chinamobile.com>
+songwenping <songwenping@inspur.com>
+sonu.kumar <sonu.kumar@nectechnologies.in>
+sujin01 <a5870771@gmail.com>
+suneethravi <ravi.sun@northeastern.edu>
+sunjia <sunjia@inspur.com>
+sunyajing <yajing.sun@easystack.cn>
+tanlin <lin.tan@intel.com>
+tengqm <tengqim@cn.ibm.com>
+tianhui <tianhui@awcloud.com>
+timothy-symanczyk <timothy_symanczyk@symantec.com>
+ting wang <bx_wang@outlook.com>
+ting.wang <ting.wang@easystack.cn>
+venkata anil <anilvenkata@redhat.com>
+venkatamahesh <venkatamaheshkotha@gmail.com>
+waf <ekrmdhsl7@gmail.com>
+wanghong <w.wanghong@huawei.com>
+wangxiyuan <wangxiyuan@huawei.com>
+wangzihao <wangzihao@yovole.com>
+whoami-rajat <rajatdhasmana@gmail.com>
+wingwj <wingwj@gmail.com>
+wu.chunyang <wu.chunyang@99cloud.net>
+wu.chunyang <wuchunyang@yovole.com>
+wu.shiming <wushiming@yovole.com>
+wuyuting <wytdahu@gmail.com>
+xfrnk2 <xfrnk2@gmail.com>
+xiexs <xiexs@cn.fujitsu.com>
+yaeeee <rim0399@naver.com>
+yang wang <wangy@rc.inesa.com>
+yangweiwei <yangweiwei@cmss.chinamobile.com>
+yangxi <yang.xi@99cloud.net>
+yanpuqing <yanpq@awcloud.com>
+ycx <yanpq@awcloud.com>
+yfzhao <dsware@126.com>
+youngho choi <0505zxc@gmail.com>
+yushangbin <yushb@gohighsec.com>
+zeze <thwjd2717@gmail.com>
+zhang.lei <zhang.lei@99cloud.net>
+zhang.xiuhua <zhang.xiuhua@99cloud.net>
+zhangbailin <zhangbailin@inspur.com>
+zhangboye <zhangboye@inspur.com>
+zhanghongtao <zhanghongtao0826@126.com>
+zhangoic <zhangoic@163.com>
+zheng yin <yin.zheng@easystack.cn>
+zhengsenyan <zhengsy_sean@126.com>
+zhiyong.dai <zhiyong.dai@easystack.cn>
+zhiyuan_cai <luckyvega.g@gmail.com>
+zhouhenglc <zhouhenglc@inspur.com>
+zhouqi <qi.zhou@easystack.cn>
+zhu.boxiang <zhu.boxiang@99cloud.net>
+zhufl <zhu.fanglei@zte.com.cn>
+zhurong <aaronzhu1121@gmail.com>
+Édouard Thuleau <ethuleau@juniper.net>
diff -pruN 7.4.0-3/ChangeLog 8.1.0+git2025070715.9d3a956a-0ubuntu2/ChangeLog
--- 7.4.0-3/ChangeLog	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/ChangeLog	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1,3915 @@
+CHANGES
+=======
+
+* Add metadata as a filter condition when listing volumes
+* Remove duplicate Python version declarations
+* Migrate setup configuration to pyproject.toml
+* Replace deprecated datetime.utcfromtimestamp
+* Fix openstack image import --method web-download --uri 'invalid value'
+* Security-groups: Temporarily ignore is\_shared
+* identity: Remove unnecessary helper
+* bug fix volume group show command
+
+8.1.0
+-----
+
+* evacuate: respect original SHUTOFF state in --wait completion
+* Fix missing 'options' field in 'user show' command
+* Identity: Migrate 'group' commands to SDK
+* tests: Simplify mocking in image tests
+* identity: Normalise output of application credentials commands
+* network: Allow multiple FIP filter opts
+* volume: Migrate 'volume delete' to SDK
+* volume: Temporarily ignore new volume columns
+* volume: Split v2, v3 create, delete commands
+* volume: Migrate 'snapshot show', 'snapshot list' to SDK
+* volume: Migrate 'snapshot set', 'snapshot unset' to SDK
+* volume: Migrate 'snapshot create' to SDK
+* volume: Migrate 'snapshot delete' to SDK
+* volume: Add v3-specific volume snapshot module
+* tests: Use SDK mocks for SDK-based commands
+* volume: Migrate 'backup set', 'backup unset' to SDK
+* volume: Migrate 'service \*' to SDK
+* volume: Add v3-specific volume service module
+* volume: Migrate 'block storage log level \*' to SDK
+* Add a column to all\_projects tag of server list cmd
+* Fix incorrect warning with --password-prompt option
+* compute: Fix key used for NIC fixed IP field
+* identity: Add missing user argument
+* identity: Fix listing of applications credentials by user
+* Bump Python version used for linters to 3.10
+* Drop support for Python 3.9
+* Add support for spice-direct console types
+* Update README
+* Add labels to Dockerfile
+* Update the docker image to python3.12
+* zuul: Remove osc-upload-image, osc-promote-image jobs
+* tests: Stop returning FakeResource in compute tests
+* tests: Remove sdk prefix
+* tests: Remove dead code
+* tests: Remove use of legacy resource helpers
+* Require confirmation to reset server state
+* Fix 'openstack keypair list --project <project>'
+* Don't warn about unsupported version with SDK-based commands
+* Workaround for failing tests on openstacksdk change
+* Add support for showing scheduler\_hints in server details
+* Refactor network fakes to sdk properties PART6
+* Refactor network fakes to sdk properties PART 5
+* volume: Make better use of argparse
+* image: Migrate 'create image' volume calls to SDK
+
+8.0.0
+-----
+
+* tests: Rename 'compute\_sdk\_client' -> 'compute\_client'
+* compute: Migrate to 'compute' client alias
+* Remove use of formatter function
+* Imported Translations from Zanata
+* Remove use of formatter function
+* Prepare for osc-lib changes
+* pre-commit: Enable mypy
+* typing: Indicate another tuple to be extended
+* docs: Remove irrelevant TODO
+* volume: Remove Cinder v1 support
+* docs: Migrate remaining block storage commands to autocommand
+* Remove contributor specs
+* Permit use of tuple API\_VERSIONS
+* identity: Migrate 'endpoint' commands to SDK
+* typing: Resolve incompatible operand issues
+* typing: Correct type for missing attributes
+* typing: Remove use of optional imports
+* typing: Use consistent types
+* typing: Add types for empty dicts, tuples
+* typing: Indicate tuples to be extended
+* pre-commit: Bump versions
+* Fix neutron typos and formatting
+* Return the \`\`port\`\` column headers expected in the list command
+* Add filters to search for enabled/disabled users and projects
+* [Neutron] Add "qos-policy" parameter to router creation command
+* Fix networking quota usage show
+* Replace description-content-type by its underscore name
+* Specifying project-domain for project
+* zuul: Make image job non-voting
+* Remove tags from README
+* Prepare for ruff bump
+* Update master for stable/2025.1
+* Add libpcre3-dev in bindep.txt for pcre.h
+* Fix image import --disallow-failure flag
+* identity: Fix 'trust' commands to work with SDK
+* Fix missing space in help messages
+
+7.4.0
+-----
+
+* Fix credential creation
+* Add four new network agent types to the list command filter
+
+7.3.1
+-----
+
+* [Neutron] Fix the "port show" command for trunk details
+* [Neutron] Support \`\`uplink-status-propagation-updatable\`\` extension
+* handle 'router create --flavor' option
+* [Neutron] "uplink-status-propagation" enabled by default
+
+7.3.0
+-----
+
+* Add "qinq-vlan" and "no-qinq-vlan" params to the "network create" cmd
+* Temporary ignore "is\_vlan\_qinq" column in the output
+* Identity: Deprecate \`--region None\` in limits/registered limits
+* Update README for use python3
+* Get "security\_groups" when port list
+* Show final image state after image create
+* Identity: Migrate 'role' commands to SDK
+* Add the trunk subports information to the port list command
+* Fix: Volume backup restore output
+* identity: Migrate 'trust' commands to SDK
+* tests: Stop setting attributes on class
+* Adopt sdk\_fakes for compute.test\_server\_volume
+* Adopt sdk\_fakes for compute.test\_server\_group
+* Adopt sdk\_fakes for compute.test\_hypervisor
+* Adopt sdk\_fakes for compute.test\_usage
+* Adopt sdk\_fakes for compute.test\_service
+* Adopt sdk\_fakes for compute.test\_keypair
+* Adopt sdk\_fakes for compute.test\_console
+* Adopt sdk\_fakes for compute.aggregate
+* identity: Migrate 'service provider' commands to SDK
+* quota: Catch correct exception type for Compute quotas
+* tests: Add functional test for adding, removing SGs
+* compute: Workaround bug #2089821
+* Fix: extend in-use volumes check
+* network: Make better use of argparse
+* compute: Add server create --no-security-group option
+* Remove ceilometer service overrides
+* identity: Migrate 'domain' commands to SDK
+* identity: Migrate \`region\` commands to SDK
+* reno: Update master for unmaintained/2023.1
+* identity: Migrate 'credential' commands to SDK
+* Replace deprecated datetime.utcnow()
+* requirements: Remove unused test deps
+* Skip tips jobs on pre-commit config update
+* common: Use correct argument for volume limits
+* Add "trusted" attribute to the "port"
+* Fix ignored --user-domain in role assignment list
+* Show Created At column for volume backups in v3
+* remove project from network flavor profile
+
+7.2.1
+-----
+
+* clientmanager: Check for 'block-storage' service type
+* Fix volume backup show by name
+
+7.2.0
+-----
+
+* Always resolve domain id
+* identity: in \`service set\` command, don't pass the enable option when it is None
+* evacuate SDK actually uses admin\_pass param
+* identity: Don't pass unset options when creating user
+* Add status filtering options to port list
+* identity: Migrate 'access rule' commands to SDK
+* tests: Add functional test for access rules
+* evacuate: Fix password parameter name for SDK
+* Handle NotFoundException when listing floating IPs
+* pre-commit: Migrate pyupgrade to ruff
+* pre-commit: Migrate bandit to ruff
+* Removed the emit\_duplicated\_warning() funtion
+* compute: Fix --host in server list for new openstacksdk
+* Update master for stable/2024.2
+
+7.1.0
+-----
+
+* pre-commit: Migrate from black to ruff format
+* trivial: Remove unnecessary trailing comma
+* pre-commit: Migrate from flake8 to ruff
+* pre-commit: Bump versions
+* identity: Use previous naming for 'service show' fields
+* identity: Use previous naming for 'application credential show' fields
+* compute: Make 'hypervisor show' a bit faster
+* compute: Add 'uuid' column to aggregate list
+* compute: Only pass admin\_password on rebuild if set
+* quota: Allow 'quota set' to function without volume service
+
+7.0.0
+-----
+
+* Bump requests minimal version
+* Respect --skip-resource when deleting
+* Add callback on plugin load failure
+* Drop support for Python 3.8
+* Add Python 3.12 classifier
+* tests: Remove aliasing from extensions test
+* Remove TestServer base class
+* Remove python-novaclient
+* compute: Allow adding, removing multiple SGs
+* quota: Migrate 'quota \*' to SDK
+* quota: Split up 'quota list' command
+* quota: Default network quotas to not force
+* quota: Add 'quota set --default' option
+* quota: Remove deprecated quota options
+* quota: Move nova-network-related quota
+* tests: Remove references to novaclient methods
+* network: Replace use of in-tree API client
+* compute: Migrate 'server create' to SDK
+* identity: Migrate 'application credential' commands to SDK
+* identity: Migrate 'service' commands to SDK
+* compute: Prevent use of conflicting v\*-fixed-ip for 'server create --nic'
+* compute: Migrate 'server evacuate' to SDK
+* compute: Migrate remaining server actions to SDK
+* compute: Migrate 'server rebuild' to SDK
+* compute: Avoid third API call during 'server show'
+* compute: Always use SDK client to display server
+* compute: Migrate 'server set', 'server unset' commands
+* compute: Migrate 'server migrate' to SDK
+* compute: Migrate 'server add/remove security group' to SDK
+* common: Migrate 'limits show' to SDK
+* volume: Migrate 'volume list' to compute SDK
+* volume: Migrate 'volume attachment \*' to SDK
+* tests: Migrate to 'set\_xxx\_api\_version' helpers
+* tests: Add ability to configure fake server API version
+* volume: Add v3-specific volume transfer module
+* volume: add v3-specific volume type module
+* volume: Add v3-specific volume module
+* volume: Add v3-specific volume backup module
+* docs: Remove references to novaclient
+* compute: Migrate remaining tests to SDK objects
+* compute: Migrate 'host set' to SDK
+* compute: Migrate 'agent \*' to SDK
+* network: Migrate 'port list' to compute SDK
+* compute: Migrate tests for ShowServer to SDK objects
+* Fix: incremental volume backup
+* docs: Fix indentation
+* compute: Remove unnecessary try-except
+* Followup: Reduce LOC in volume v3 service
+* Add cluster to volume service list
+* Add tests for 'default security group rule create'
+* Add volume snapshot unmanage support
+* Add DeleteVolumeSnapshot class to v3
+* Identity: Migrate 'role assignment' commands to SDK
+* tox: Add testenv descriptions
+* Add support for volume unmanage
+* Remove admin only text from 'port create' help text
+* Drop direct dependency on simplejson
+* Show Created At column for volume backups
+* Remove clients of retired projects
+* Add DeleteVolume class to v3
+* Add support for managing volumes
+* Add CreateVolume class to v3
+* Fix tests on Python 3.12
+* identity: Make better use of argparse
+* Router flavor\_id can be a name
+* pre-commit: Add pyupgrade hook
+* reno: Update master for unmaintained/zed
+* tests: Fix trivial sorting issue
+* trivial: Prepare for pyupgrade pre-commit hook
+* tox: Remove bandit skips, run via pre-commit
+* tox: Add functional-pyNN jobs
+* pre-commit: Bump versions
+* Improve output of 'server migrate --wait'
+* Add image metadef resource type association commands 'create', 'list', 'delete'
+* tests: Remove use of unnecessary fake argparse Namespace
+* tests: Use consistent shortcut to fake identity client
+* Identity: Properly list users in a group in 'user list' commands
+* volume: Deprecate '--retype-policy' in favor of '--migration-policy'
+* Tox: Fix install commands for unit-tips and functional-tips
+* identity: Migrate 'user' commands to SDK
+* tests: Add identity v2, v3 FakeClientMixin
+* Update master for stable/2024.1
+* image cache clear: fix value of default target
+* refectoring: remove duplicate declaration
+* Fix typo in the list of Glanceclient/OSC commands
+* refectory: remove unreachable code
+
+6.6.0
+-----
+
+* reno: Update master for unmaintained/xena
+* reno: Update master for unmaintained/wallaby
+* reno: Update master for unmaintained/victoria
+* Add router default route BFD/ECMP options
+* Add support for managing external gateways
+* router: Use plural form for storage of \`\`--fixed\_ip\`\` argument
+* Parse external-gateway argument in separate helper
+* Add NUMA affinity policy options "socket"
+*  Bug Fix, Default SG Rule Custom SG
+* Adds CLI support for \`\`glance md-object-property-show\`\`
+* Do not sort subnet dns\_nameservers field
+* Adds CLI support for \`\`glance md-object-update\`\`
+* trivial: Don't ignore missing resources
+* reno: Update master for unmaintained/yoga
+* trivial: Fix typo
+
+6.5.0
+-----
+
+* doc: magnumclient provides a OSC plugin
+* image: Trivial fixes
+* Introduce \`schema\_version\` in the federated attribute mapping API
+* Add "hardware\_offload\_type" attribute to "port"
+* Add support for showing requested az in output
+* pre-commit: Bump linter versions
+* doc: Add manilaclient as a OSC plugin
+* Revert "Temporarily drop aodhclient from doc build"
+* doc: Drop tripleoclient
+* doc: Remove RSD subcommand
+* doc: Remove Searchlight subcommands
+* Explicitly specify namespace fields for output
+* Update python classifier in setup.cfg
+* Correct error message for "create server --wait"
+* Fix --use-prefix-delegation subnet create argument
+* Adding CLI command for \`\`glance member-get\`\`
+* trivial: Place positional opts last
+* network: Clarify purpose of default sg rules
+* Doc: Fix volume snapshot commands
+* Fix availability zone list command
+* volume list: Don't call nova if no volume is attached
+
+6.4.0
+-----
+
+* Fix clearing of dns\_domain and description on a network by setting to empty strings
+* tests: Handle missing extensions in network tests
+* tests: Check for DHCP agents first in DHCP test
+* [codespell] fix typos in doc,tests and help messages
+* Adds command \`\`image metadef object delete\`\`
+* test: Ignore 'OS\_' environment variables
+* parseactions: Use ArgumentError, not ArgumentTypeError
+* Remove unnecessary file
+* Use CommandError, not SystemExit, to exit
+* compute: Address bug in shelve offload logic
+* tests: Remove unused flag
+* tests: Enable logging fixture
+* tests: Remove prints
+* tests: Handle missing extensions in network tests
+* tests: Fix API extension check
+* tests: Centralise check for networking service
+* Adds command \`\`image metadef object list\`\`
+* image: Fix the default description of image visibility
+* Adds command \`\`image metadef object show\`\`
+* Add pagination helpers
+* compute: Add 'server create --server-group' option
+* Adds command \`\`image metadef object create\`\`
+* Update the docker image to python3.11
+* Update from storyboard to launchpad pt. 2
+* volume: Support same\_host, different\_host hint as list
+* Migrate resource filter commands to SDK
+* Removed start, end time format. Before fix, openstack usage list command resulted 'str' object has no attribute 'isoformat' error
+* trivial: Make better use of argparse
+* volume: Add alias for volume type AZs
+* volume: Add aliases for common volume type props
+* volume: Allow filtering volume types by properties
+* Switch back to Launchpad
+* Add support for default security group rule CRUDs
+* Add "image metadef property set" command
+* Add "image metadef property delete" command
+* Add "image metadef property create" command
+* Add "image metadef property show" command
+* Add "image metadef property list" command
+* Migrate volume backend commands to SDK
+* image: Add support for cache commands
+* tests: Add compute v2 FakeClientMixin
+* tests: Use consistent shortcut to fake compute client
+* tests: Add volume v1, v2, v3 FakeClientMixin
+* tests: Use consistent shortcut to fake volume client
+* tests: Use central SDK client fake
+* Update branch regexes for tips jobs
+* Add is\_incremental to ListVolumeBackup
+* Update master for stable/2023.2
+* tests: Explicitly specify port fields for output
+* Remove use of oslo.utils
+* volume: Deprecate '--detailed' options
+
+6.3.0
+-----
+
+* Propocol release versions properly
+* Fix ReleaseNotes build
+* tests: Add image v1, v2 FakeClientMixin
+* tests: Use consistent shortcut to fake image client
+* tests: Remove FakeImagev1Client, FakeImagev2Client
+* tests: Add network v2 FakeClientMixin
+* tests: Use consistent shortcut to fake network client
+* tests: Remove FakeNetworkV2Client
+* Remove project purge image commands
+* Migrate 'extension list' to SDK
+* Migrate 'availability zone list' to SDK
+* Fix "server create"command with --boot-from-volume
+* volume: Migrate 'volume group snapshot' commands to SDK
+* tox: Bump min\_version to 4.3.0
+* Add --skip-resource option to project cleanup
+* Add the flavor-id option to router create
+* Migrate backup commands to SDK
+* Check the default role list before adding a new one
+* Adding image stores info command
+* Adding \`\`image delete --store\`\` and \`\`image import info\`\` commands
+* Add a warning for resizing servers booted from volumes
+* Update the underlying python containers to "3.10-bookworm"
+* docs: Add examples of common auth methods
+* doc: Split image command documentation
+* Add image metadef resource type command 'list'
+* Migrate 'volume summary' command to SDK
+* tests: Use a new project for quota tests
+* Allow multiple \`--remove-tag\` in \`project set\`
+* Fix "access rule" commands to only use ID
+* tox: Disable E501
+* Neutron port hints
+* trivial: Remove duplicate definitions
+* Dropping the use of 'addFixedIp' server action
+* compute: Fix formatting of 'server show'
+* docs: Migrate volume commands to autoprogram-cliff
+* volume: Add 'volume qos set --no-property' option
+* volume: Make better use of argparse
+* volume: Add 'volume type set --private/--public'
+* compute: Fix bug with start/stop server
+* Allow server rebuild --wait for SHUTOFF servers
+* tests: Use SDK objects where expected
+* tests: Remove unnecessary nesting of compute resources
+* tests: Reorder compute fakes
+* Migrate 'volume revert' command to SDK
+* pre-commit: Enable black
+* Ignore black changes
+* Blacken everything else
+* Blacken openstackclient.api
+* Blacken openstack.common
+* Blacken openstackclient.image
+* Blacken openstackclient.object
+* Blacken openstackclient.identity
+* Blacken openstackclient.network
+* Blacken openstackclient.volume
+* Blacken openstackclient.compute
+* Use pre-commit for 'pep8' tox target, bump versions
+* Address pre-commit issues
+* compute: Generate SSH keypairs ourselves
+* Migrate 'server event \*' commands to SDK
+* Fix pep issue in the network service provider
+* Adding \`\`image import\`\` command
+* Silence warnings from openstacksdk
+* compute: Migrate 'reboot server' to SDK
+* Add an updated tips job running on py310
+* Show Network QoS rules one per line
+* "hypervisor list --matching" showed the wrong result
+* Docs: Update glance command mapping
+* Fix --security-group for port list
+* Update master for stable/2023.1
+
+6.2.0
+-----
+
+* Add missing documentation for state options for "image set"
+* zuul: Merge osc-functional-devstack-base into only child
+* Wait for volume being available to set bootable or readonly
+* doc: Update nova command mapping
+* Deprecate positional args for 'volume group create'
+
+6.1.0
+-----
+
+* Add options to create volume group from source
+* Add block storage manageable list commands
+* Add block storage cleanup command
+* Add block storage log level {list, set} commands
+* Add volume revert command
+* Add auto-approve option to project cleanup
+* volume: Remove duplication from 'consistency group create' opts
+* Move network trunk commands from python-neutronclient
+* Add volume summary command
+* tests: Use fake SDK Migration object
+* Excluding test code from coverage reports
+* Drop default from ask\_user\_yesno question
+* Fix tox v4 compatibility
+* Add plugin doc page for cyborg
+* Update 'host list' and 'host show' command to use sdk
+* Remove unused helpers for legacy novaclient
+* Switch server shelve, unshelve to SDK
+* compute: Switch server restore to SDK
+* Remove unnecessary 'self.methods'
+* Switch server start, server stop to SDK
+* Switch server lock, unlock to sdk
+* compute: 'server volume update' -> 'server volume set'
+* Switch server volume update to sdk
+* Switch list server volume to sdk
+* Switch server dump create to using sdk
+* Finish switching server migration to sdk
+* Fix server list error with --long and -c options
+* Create a functional test case for hypervisor list and show
+* Fix functional-tips job
+* Migrate hypervisor stats commands to SDK
+* Fix really long help strings
+* Fix parameter handling in server add fixed ip cmd
+* Use the SDK for server show
+* Add qos rule type filtering
+* Add image metadef namespace command
+* Updating the glanceclient reference doc
+* docs: Fix typos
+* compute: Allow users to manually specify bootable volumes
+* tests: Add test for multiple blocks devices
+* image: Fail if we can't find an image
+* image: Rename import
+* image: Add support for additional image import methods
+* Revert "Don't look up project by id if given id"
+* Use the SDK in server migration list
+* docs: Document how we manage API versions
+* docs: Describe common actions found in OSC
+* Use the compute SDK in server list
+* tests: Convert network tests to use 'parse\_output'
+* tests: Convert compute tests to use 'parse\_output'
+* tests: Convert identity tests to use 'parse\_output'
+* tests: Convert volume tests to use 'parse\_output'
+* tests: Convert image tests to use 'parse\_output'
+* Adding volume backend commands to volume v3
+* docs: Typo fix
+* docs: Small cleanup of human interface guide
+* Add test for creating volume from source
+* Change --size helptext to include backup
+* Add option to create volume from backup
+* Docstring fix for CreateVolumeAttachment class
+* Moved hypervisor to the SDK
+* image: Add 'image import' command
+* image: Add 'image stage' command
+* image: Simplify handling of data provided via stdin
+* image: Ignore '--progress' if providing image data from stdin
+* Add baremetal agent type list filtering
+* tests: Convert more functional tests to use 'parse\_output'
+* tests: Move json decoding to base test class
+* compute: Add missing microversion check for networks
+* compute: Fix '--network none/auto' handling
+* zuul: Remove nova-network tests
+* Add note about microversion 2.87 in server rescue help
+* compute: Add '--no-network', '--auto-network' flags
+* Improve \`server dump create\` helptext
+* Added "openstack image metadefs namespace list" command
+* Use the compute SDK in usage commands
+* quota: Deprecate "force" behavior for network quotas
+* quota: Fix issues with delete quota command
+* tests: Remove unnecessary nesting of volume resources
+* tests: Remove duplicate FakeImagev1Client
+* tests: Move fake clients to top of file
+* quota: Trivial style fixups
+* quota: Deprecate 'quota show --class', 'quota set --class' arguments
+* quota: Allow showing project-specific quotas
+* quota: Add 'quota show --usage' option
+* quota: Simplify logic used to list, show quotas
+* Fix server evacuate command
+* Speed up standard flavor list command
+* quota: Add support for detailed volume quotas
+* quota: Add 'quota delete' command
+* doc: Update cinder command mapping
+* Improve help text for network create --external
+* Switch to 2023.1 Python3 unit tests and generic template name
+* Update master for stable/zed
+* Fix wrong assertion methods
+* image: Add 'image task list' command
+* image: Add 'image task show' commands
+* Run swift in -tips job
+* Replace assertItemsEqual with assertCountEqual
+* Adding missing command mapping in docs
+* volume: Volume names are optional
+* compute: Add support for microversion 2.93
+* compute: Require image when rebuilding a volume-backed server
+* Add address-scope to NDP proxy tests
+* network: Add tenant project filter for RBAC list
+* Add router ndp proxy commands
+* Fix missing closing brackets in metavar
+* Remove invalid note from requirements files
+* Bump python-novaclient version
+* Microversion 2.91: Support specifying destination host to unshelve
+* remove unicode prefix from code
+
+6.0.0
+-----
+
+* Fix documents for replaced configuration name
+* Migrate server\_groups to the new API
+* config: Also mask non-prefix config
+* Update the Nova CLI Mapping Guide
+* Add authorization\_ttl for identity providers
+* Add port ranges on floating ip portforwardings cli
+* docs: Add missing command mappings
+* Drop support for Python 3.6, 3.7
+* pre-commit: Allow unsafe YAML
+* Add support for CRUD operations for QoS minimum packet rate rule
+* image: Split image creation depending on service
+* image: Make better use of argparse
+* Fix: create image from volume command
+* image: Trivial style changes
+* Skip test\_quota\_network\_set\_with\_force func test
+* Don't show tenant\_id in network objects
+* Allow users to list all images
+* Migrate osc-tox-py3N-tips to Python 3.8
+* Add 'Host Status' to 'server list --long' with >= v2.16
+* volume: Correct output of 'volume attachment create'
+* Allow to filter multiple tags for image list
+* Stop testing lower-constraints
+* volume: Add 'block storage resource filter list' command
+* volume: Add 'block storage cluster \*' commands
+* Refactor network fakes to sdk properties PART 4
+* Stop using private \_is\_uuid\_like method
+* Add more filter option of columns for server list -c COLUMN
+* compute: Only retrieve necessary images
+* Add trustor and trustee filtering to trusts list
+* Allow "--force" flag in quota network commands
+* Refactor network fakes to sdk properties PART 3
+* compute: Add 'Security Groups' for 'server list'
+* Refactor network fakes to sdk properties PART 2
+* Refactor network fakes to sdk properties PART 1
+* Refactor "volume backup restore" command
+* compute: Move server migrations commands to their own file
+* compute: Allow retrieval of migration by UUID
+* volume: fix backup list of deleted volume
+* Add Python3 zed unit tests
+* Update master for stable/yoga
+* Fix metavars and typos in local\_ip
+
+5.8.0
+-----
+
+* Add support for setting extra DHCP options on existing ports
+* volume list: don't fail when there's no compute service
+* Fix 'server event list|show' for deleted servers
+* docs: Document additional 'server migration' commands
+* Add support for 'remote-managed' vnic type
+* Don't fail on extlinks warnings for reno build
+* Support Neutron Local IP CRUD
+* Get rid of tenant\_id in the network commands
+* Switch compute service list, delete and set to sdk
+* Skip original\_name from flavor info
+* Fix volume set functional test
+* Add location to fake network objects
+* Hide location columns for network objects
+* compute: Pass through args to ssh
+* compute: Fix weird option definition for 'server ssh'
+* compute: Return information about fixed IP
+* Switch add fixed IP to SDK
+* tests: Improve logging for executed commands
+* Allow setting gateway when creating a router
+* Fix RemoveServerVolume
+* Add network update quota "limit\_check" parameter
+* Add --security-group to port list
+* compute: Show flavor in 'server list' with API >= 2.47
+* compute: Reorder building of columns for 'server list'
+* Switch server suspend and server resume to SDK
+* Switch server pause and server unpause to SDK
+* Switch openstack server remove port/network to using sdk
+* Allow unset port's host\_id
+* Switch command server remove volume to sdk
+* Add functional test for server add/remove volume
+* Temporarily drop aodhclient from doc build
+* Switch command server add volume to sdk
+* Add missing command mapping in nova
+* image: Sanity check the 'SetImage' command
+* tests: Update fake image client in tests
+* image: Remove FakeImage test helper
+* image: Remove dead test helper methods
+* Switch server image create to SDK
+* Switch openstack server add port/network to using sdk
+
+5.7.0
+-----
+
+* compute: Return details of attached volumes
+* compute: Use correct command class for 'show migration'
+* compute: Don't warn if disk overcommit params unset
+* Switch server backup to sdk
+* Fix typos
+* Remove remnants of 'six'
+* Remove 'get\_osc\_show\_columns\_for\_sdk\_resource' duplicates
+* tox: Ignore virtualenvs for pep8 environment
+* compute: Fix filtering servers by tags
+* Update the Nova CLI docoder document
+* Update the Nova CLI decoder document
+* Remove non-working code after method return
+* Add --trusted-image-cert option for server create
+* Fix that the path of functional test
+* Add Python3 yoga unit tests
+* Update master for stable/xena
+* Replace assertItemsEqual with assertCountEqual
+* compute: Add support for microversion 2.89
+* compute: Add support for microversion 2.90
+
+5.6.0
+-----
+
+* [community goal] Update contributor documentation
+* Fix typo error in listing server's column name
+* Show "Forced Down" compute service status with --long
+* Correct REST API response fields for /os-migrations API
+* volume: Add missing 'volume list --offset' parameter
+* Fix TestListMigrationV223 test class MIGRATION\_COLUMNS
+* tests: Handle removal of block-storage v2 API
+* volume: Add 'volume transfer request create --(no-)snapshots' option
+* Moving IRC network reference to OFTC
+* cinder: Remove redundant command
+* Correct the tox option for skipping sdist generation
+* compute: Better help text for 'openstack server set --state'
+* compute: Note that '--password' is deployment-specific
+* volume: Add more missing 'volume backup \*' options
+* volume: Add 'volume group snapshot \*' commands
+* L3 conntrack helper: Use singular name consistently
+* Add support for Neutron's L3 conntrack helper resource
+* volume: Add 'volume group type \*' commands
+* volume: Add 'volume group \*' commands
+* tests: Rename 'FakeType' -> 'FakeVolumeType'
+* volume: Add missing 'volume backup \*' options
+* volume: Add 'volume message \*' commands
+* volume: Add 'volume attachment \*' commands
+* volume: Allow more versions
+* docs: Update neutronclient comparison doc
+* docs: Update glanceclient comparison doc
+* docs: Update novaclient comparison doc
+* docs: Update cinderclient comparison doc
+* Include hosts in aggregate list --long
+* Changed minversion in tox to 3.18.0
+* compute: Fix typo
+* setup.cfg: Replace dashes with underscores
+* Make functional Neutron tests running fine on ML2/OVN environments
+* Allow to send extra attributes in Neutron related commands
+* compute: Update 'server resize --revert', '--confirm' help
+* Add check for cinderclient.v2 support
+* Set ML2/OVS backend explicitly in the devstack jobs
+* Fix the functional-tips tox environment
+* openstack image create: honor protection/visibility flags
+* Replace assertItemsEqual with assertCountEqual
+* requirements: Drop os-testr
+* hacking: Remove references to encoding
+* Implements hide image
+* Add Python3 xena unit tests
+* Update master for stable/wallaby
+* Hides prefix\_length column in subnet show output
+* network: Make 'network qos rule create --type' option required
+* volume: Re-add accidentally deleted test
+* network: Add support for vnic-type vdpa
+
+5.5.0
+-----
+
+* Add --subnet-pool to subnet list
+* Update the file paths mentioned in README.rst
+* Add pre-commit
+* compute: Remove 'file://' prefix from '--block-device'
+* Update volume create documentation
+* network: Add missing subnet unset --gateway <subnet-id>
+* compute: Add support for loading BDMs from files
+* compute: Add functional tests for --block-device
+* Add --name to port list
+* Add 'address\_group' type support to rbac commands
+* project cleanup
+* compute: Remove deprecated 'server migrate --live' option
+* compute: Deprecate 'server create --file'
+* compute: Stop silently ignore --(no-)disk-overcommit
+* compute: Auto-configure shared/block live migration
+* compute: Add 'server create --block-device' option
+* compute: Remove references to optional extensions
+* compute: Add missing 'server create' options
+* compute: Improve 'server create --block-device-mapping' option parsing
+* compute: Rename 'server migrate (confirm|revert)'
+* compute: Add 'server migration show' command
+* Rename FakeServerMigration to FakeMigration
+* compute: Add support for 'server boot --nic ...,tag=<tag>'
+* compute: Improve 'server create --nic' option parsing
+* compute: Shuffle options for 'server create'
+* compute: Add missing options for 'server event list'
+* compute: Add missing options for 'server group list'
+* compute: Add 'server \* --all-projects' option
+* Add device profile to \`\`port\`\`
+* compute: Improve 'server migration list' options
+* compute: Add '--force' option to 'server delete'
+* compute: Add missing options for 'hypervisor list'
+* Support remote-address-group in SG rules
+* compute: Add 'server volume update' command
+* network: Address nits for I3c313fc9329837dde67815901528a34dca98ebcc
+* Add reno for change Ic3c555226a220efd9b0f27edffccf6c4c95c2747
+* Remove retired Karbor support
+* Add 'server unshelve --wait' option
+* Add 'server shelve --offload', 'server shelve --wait' options
+* compute: Add 'server volume list' command
+* compute: Add missing options for 'server image create'
+* tests: Remove unused fake method
+* compute: Add missing options for 'keypair list'
+* compute: Add missing options for 'server set'
+* compute: Add missing options for 'server list'
+* trivial: Use plural for appended parameters
+* compute: Add 'server show --topology' option
+* compute: Add 'server group create --rule' option
+* compute: Fix 'hypervisor show -f yaml' output
+* compute: Fix 'server group \* -f yaml' output
+* compute: Fix 'usage \* -f yaml' output
+* compute: Fix 'server \* -f yaml' output
+* Add support '--progress' option for 'image create'
+* Support Neutron Address Group CRUD
+* image: Unset properties rather than setting to None
+* Add project field in image list subcommand
+* trivial: Cleanup docs for 'server list'
+* compute: Add missing options for 'server rebuild'
+* Add 'flavor list --min-disk', '--min-ram' options
+* Make use of comparable 'FormattableColumn' subclasses
+* Remove retired Searchlight support
+* Update lower-constraints
+* Fix lower-constraints job
+* Add support for token caching
+* trivial: Cleanup docs for 'server rebuild'
+* Add documentation about login with federation
+* Switch compute aggregate functions to SDK
+* Switch compute flavors from novaclient/direct to SDK
+* Let autoprogram-cliff know who's running
+* Add NODE and HOST parameters in "server create" help text
+* Add option to filter instances by AZ
+* stop image downloads to memory
+* Add "fields" parameter to ListPort query
+* trivial: Document removal of support for agents
+* tests: Remove 'agent' functional tests
+* Allow to resize in-use volumes
+* Resolve issues with 'server migration list'
+* Switch 'openstack keypair' ops to use SDK
+* functional: Remove test for 'quota set --force'
+* Remove unnecessary test
+* Remove references to Python 2.7
+* Add a few selectable fields to the "openstack server list" output
+* Add 'openstack server evacuate' command
+* Fix formatting of the flavor properties
+* Compute: Add user id support for keypair
+* trivial: Rework 'CreateServer' function
+* update lower-constraints.txt
+* Replace deprecated UPPER\_CONSTRAINTS\_FILE variable
+* Switch console url show operations to SDK
+* Remove references to setuptools
+* Remove the unused coding style modules
+* Add support for 'keypairs list --project' parameter
+* Add support for 'keypairs list --user' parameter
+* Compute: Add tags support for server
+* Validate 'server group create --policy' option
+* Add 'openstack server migration list --type' option
+* Cleanup of 'server migration list' command
+* Add 'server migration force complete' command
+* Add 'server migration abort' command
+* compute: Add --password option for openstack server create
+* Remove oslo.utils
+* zuul: Stop testing against Tempest
+* Add an error message when server bind floating IP
+* Compute: Add tag support for server add fixed ip
+* Compute: Add tag support for server add network
+* Compute: Add 'keypair create --type' parameter
+* Compute: Add tag support for server add port
+* Compute: Add tag support for server add volume
+* Remove usage of six
+* Switch openstack console log show operation to use OpenStackSDK
+* Fix: port attribute name propagate\_uplink\_status
+* Restore behavior of image create with same name
+* Add Python3 wallaby unit tests
+* Update master for stable/victoria
+
+5.4.0
+-----
+
+* Add server migration list CLI
+* Remove install unnecessary packages
+* Remove None valued network quota entries
+* bump py37 to py38 in tox.ini
+* Output correct json for security groups in 'openstack server show'
+* Remove install unnecessary packages
+* Fix gate due to switch to focal
+* Fix --image-property option in 'create server'
+* Update developing.rst
+* Support tagging Neutron ports on creation
+* Add source\_ip\_prefix and destination\_ip\_prefix to metering label rules
+* Show words indicating booted from volume for server image
+* Add API check for server\_groups.create
+* Add API check for server\_groups.list
+* Bypass user and group verification in RemoveRole
+* Add NUMA affinity policy parameter to "port"
+* Add id and enabled param in ListIdentityProvider parser
+* Delete the testcases that arent needed anymore
+* Fix reverted osc-lib interface change
+* Add 'openstack server create --use-config-drive'
+* Add name and enabled param in ListDomain parser
+
+5.3.1
+-----
+
+* Fix compatibility issue in 5.3
+* Add system role assignment tests for users and groups
+
+5.3.0
+-----
+
+* Fix uploading an signed image does not work if private signing key is encrypted
+* Add a command to trigger entrypoint cache creation
+* switch to stevedore for entry points
+* Make volume backup record commands available in v3
+* Remove enabling of glance v1 API
+* Expose flag for forcing use of import for images
+* Remove translation sections from setup.cfg
+* port: add --host to list command
+* Don't display Munch objects in the output
+* Revert "Format location columns in network commands"
+* Allow openstack flavor set to update flavor description using name
+* image: autogenerate docs
+* identity: autogenerate docs
+* Remove os-client-config references
+* Add cliff to libs-from-git for devstack functional tips
+* Add OpenStack Client for Manila docs
+* Remove congress
+* Replace assertItemsEqual with assertCountEqual
+* Client should parse string to boolean for value 'is\_domain'
+* Add py38 package metadata
+* Switch to newer openstackdocstheme and reno versions
+* Make container list --all work
+* Cleanup: remove a useless reference to "object"
+* Resolve PEP8
+* Correct image lookup during server rebuild
+* Add Python3 victoria unit tests
+* Update master for stable/ussuri
+* Remove Babel from requirements
+* Add '--force; parameter to 'openstack quota set'
+* Add 'subnetpool' type support to rbac commands
+* Add resource option immutable
+* Revert "Disallow setting default on internal network"
+* Use unittest.mock instead of third party mock
+* Add description field to portforwarding NAT rules
+* Support for stateless security groups
+* Cleanup Python 2.7 support
+* Add command: router add/remove route --route
+* Adding options to user cli
+* Be explicit about python version in image
+* Add libc6-dev to bindep
+* Add 'address\_scope' type support to network rbac commands
+
+5.2.0
+-----
+
+
+5.1.0
+-----
+
+* Don't look up project by id if given id
+* Complete switch from glanceclient to SDK for image service
+* Honor endpoint override from config for volume
+* Switch image to use SDK
+* Remove trailing newline from dockerhub secret
+* Fix network segment range "\_get\_ranges" function
+* Change dockerhub password
+* Bump lower constraint of MarkupSafe
+* Update image building jobs
+* Allow setting floating IP description
+* Stop configuring install\_command in tox and stop use pip
+* Build utility image for using osc
+* Allow os quota list query to filter by project
+* Add "fields" parameter to ListSecurityGroup query
+* Update http links in docs
+* Disallow setting default on internal network
+* Change 'Volume' to 'Block Storage'
+* Always display direction for security group rules
+* Add bindep file
+* Add storage policy option to create container command
+* Add qos\_network\_policy\_id to network port tests
+
+5.0.0
+-----
+
+* Complete "Drop python2 support" goal
+* Use 'KeyValueAppendAction' from osc-lib
+* Stop silently ignoring invalid 'server create --hint' options
+* Remove mention of meetings from docs
+* Incorrect title for service provider
+* Fix copypaste errors in access rule command
+* Add support for app cred access rules
+* Switch to using osc\_lib.utils.tags
+* Add unit tests and release note for dns\_publish\_fixed\_ip
+* Raise flake8-import-order version to latest
+* Raise hacking to more recent 2.0.0
+* Replace six.iteritems() with .items()
+* Show correct name for resource with quota set to zero
+* Bump tox minversion
+* Fix openstack server list --deleted --marker option
+* Fix faulthy state argument choice
+* Stop testing python 2 in tox and zuul
+* Fix router create/show if extraroute not supported
+* Provide stderr in exception when check\_parser fails
+* Microversion 2.79: Add delete\_on\_termination to volume-attach API
+* Create Volume v3 functional tests
+* Refactor AggregateTests
+* Deflate .htaccess
+* Add redirect testing
+* compute: autogenerate docs
+* openstack.cli: autogenerate docs
+* common: autogenerate docs
+* Update a stale doc reference to use :neutron-doc:
+* neutron: autogenerate docs
+* versions: Fix 'versions show' help message
+* Remove redundant OpenStackShell.prepare\_to\_run\_command
+* Use SDK to get compute API extensions
+* Fix functional tests for py3
+* Use autoprogram-cliff for remaining plugin docs
+* Doc: launchpad => storyboard
+* Link to (some) plugin doc pages
+* Add plugin doc page for watcher
+* Produce complete content for plugin docs
+* Split plugin docs per project
+* Remove plugin projects from test-requirements.txt
+* Add placement to known plugins
+* Fix plugin autodoc generation
+* Update master for stable/train
+* Fix osc-lib interface change: catch osc-lib Forbidden
+
+4.0.0
+-----
+
+* Add dns\_publish\_fixed\_ip attribute to subnets
+* Update release table for Train and 4.0.0
+* More aggregate functional race chasing
+* Add 'openstack server migrate (confirm|revert)' commands
+* Add doc and relnote for review 639652
+* Default to Cinder v3 API
+* Clean up app initialization and config
+* Follow-up: fix the invalid releasenote link
+* Microversion 2.77: Support Specifying AZ to unshelve
+* Add parent project filter for listing projects
+* Bump lower constraint of python-zunclient
+* Remove races in floating ip functional tests
+* Bump min osc-lib to 1.14.0
+* Format location columns in network commands
+* Add floating IP Port Forwarding commands
+* Bump hacking version
+* Remove token\_endpoint auth type
+* Format aggregate command fields and de-race functional tests
+* Add CLI argument tests before making changes
+* Fix functional.base.TestCase.openstack() to optionally omit --os-auth-type
+* Document 2.53 behavior for compute service list/delete
+* Add openstack server create --boot-from-volume option
+* Fix <id> description for --block-device-mapping
+* Support type=image with --block-device-mapping option
+* Fix compute service set handling for 2.53+
+* Add 'openstack server resize (confirm|revert)' commands
+* Make configuration show not require auth
+* Fix typo: "to and endpoint"
+* Fix module paths for volumev3 volume backup commands
+* openstack port create support --extra-dhcp-option
+* Mention compute service set --up|--down requires 2.11 or greater
+* Update api-ref location
+* Add host and hypervisor\_hostname to create servers
+* Support IPv6 addresses better
+* Add Python 3 Train unit tests
+* docs: clarify compute service --service option
+* Update the constraints url
+* Add Python 3 Train unit tests
+* Fix BFV server list handling with --name-lookup-one-by-one
+* Use cliff formattable columns in volume v2 commands
+* Use cliff formattable columns in volume v1 commands
+* Use cliff formattable columns in object storage commands
+* Use cliff formattable columns in image commands
+* Use cliff formattable columns in identity commands
+* Microversion 2.73: Support adding the reason behind a server lock
+* Allow "server migrate" (not live) to take "--host" option
+* Add server add/remove volume description for microversion 2.20
+* Add server event command documentation for compute API 2.21
+
+3.19.0
+------
+
+* Add changes-before attribute to server list
+* Deprecate openstack server migrate --host option
+* Remove deprecated volume commands and args
+* Batch up minor cleanups for release
+* Remove deprecated network options
+* Remove deprecated image commands
+* Remove deprecated identity commands and args
+* Remove deprecated compute commands
+* Serialize more aggregate functional tests
+* Compute: Add description support for server
+* Remove code migrated to osc-lib long ago
+* Aggregate functional test tweak
+* Update sphinx requirement
+* Rename review.openstack.org to review.opendev.org
+* Stop leaving temp files after unit test runs
+* Use cliff formattable columns in network commands
+* Blacklist Bandit 1.6.0 due to directory exclusion bug
+* Fix bug in endpoint group deletion
+* document the --timing option
+* Change default security group protocol to 'any'
+* Fix link to new opendev repo
+* Document that server dump create requires 2.17
+* Dropping the py35 testing
+* Followup opendev cleanup and test jobs
+* OpenDev Migration Patch
+* Fix docs bug link to go to storyboard rather than launchpad
+* Tweak network segment range fiunction tests
+* Before writing object data to stdout, re-open it in binary mode
+* Volume backup functional test tweak
+* Ignore case in security group rule --ethertype
+* Update master for stable/stein
+* Fix: incorrect check when no shared/private input
+* Fix service discovery in functional tests
+* Fix: set invalid None project\_id on range creation
+
+3.18.0
+------
+
+* Mention compute API 2.50 in openstack quota show --class
+* Add network segment range command object
+* API microversion 2.69: Handles Down Cells
+* Add 'security\_group' type support to network rbac commands
+* Paginate over usage list to return all usages
+* Add --attached / --detached parameter to volume set
+* Fix: Restore output 'VolumeBackupsRestore' object is not iterable
+* Typo fix
+* Disabling c-backup service for osc-functional-devstack-tips job
+* Add possibility to filter images using member\_status
+* Add support for get details of Quota
+* Fix help message of image add project
+* Fix help message of image add project
+* add python 3.7 unit test job
+* Remove str() when setting network objects names
+* Add py36 env
+* This fix removes an erroneous underscore found within the function named test\_snapshot\_delete within test\_snapshot.py found in both volume v1 and v2 of python-openstackclient
+* More state handling in volume transfer requests functional tests
+* Fix --limit option in image list sub-command
+* fix multiple server delete produce multiple new lines
+* Add floating IP filter to floating IP list command
+* Use os-cloud instead of OS env vars for functional tests
+* Add osc repo to the base job definition
+* Remove testr.conf as it's been replaced by stestr
+* More volume functional test fixes
+* Supports router gateway IP QoS
+* Support enable/disable uplink status propagation
+* Change openstack-dev to openstack-discuss
+* Add Python 3.6 classifier to setup.cfg
+* Use devstack functional base job
+* Replace assertEqual(True/False, expr) with assertTrue/assertFalse
+* Fix i18n issue
+* Add volume backup import/export commands
+* Modify the help message for 'registered limit set'
+* Updated the take\_actions for unified limits
+
+3.17.0
+------
+
+* Add project param in LimitList parser
+* image/v2: support multiple property filters
+* Handle multiple ports in AddFloatingIP
+* Add --name-lookup-one-by-one option to server list
+* trivial: modify spelling error of project
+* Remove invalid 'unlock-volume' migration arg
+* Update the Neutron CLI decoder document
+* Update release note version reference table
+* Make use of keystoneauth service-type filtering for versions
+* Improve document 'openstack complete'
+* Address issues from volume backend commands
+* Handle not having cinderclient.v1 available
+* Add volume backend pool list command
+* Add volume backend capability show command
+* Allow endpoint filtering on both project and project-domain
+* Add --key-name and --key-unset option for server rebuild API
+* Add --property option to 'server rebuild' command
+* Remove python-ceilometerclient
+* trivial: remove commented-out code
+* Add monascaclient to \`not plugins\` list
+* Fix some spaces in help messages
+* fix tox python3 overrides
+* Update the URL in doc
+* Fix help message for subnetpool default-quota value
+* Now we can add description for role creation in OSC
+* Replace port 35357 with 5000 for "auth\_url"
+* Fix 'project purge' deleting wrong project's servers and volumes
+* Add metavar for name parameter in subnet create
+* osc-included image signing (using openstacksdk)
+* Use templates for cover and lower-constraints
+* Partially Revert "Add command to unset information from Subnet-pools"
+* add lib-forward-testing-python3 test job
+* add python 3.6 unit test job
+* switch documentation job to new PTI
+* import zuul job settings from project-config
+* Deprecate volume create --project and --user options
+* Fix inconsistency (nit)
+* Detailed help message for QoS max-burst-kbps value
+* Fix broken gate jobs
+* Add DNS support to floating IP commands
+* Fix missing trailing spaces in network help messages
+* Update reno for stable/rocky
+
+3.16.0
+------
+
+* Release note cleanup for 3.16.0 release
+* Support --community in openstack image list
+* Don't sent disk\_over\_commit if nova api > 2.24
+* Fix error with image show when image name is None
+* Add command to show all service versions
+* Implement support for project limits
+* Implement support for registered limits
+* Pass volume snapshot size to volume create
+* compute: host: expand kwargs in host\_set() call
+* Fix lower-constraints.txt
+* Replace pbr autodoc with sphinxcontrib-apidoc
+* Skip calls to glance and nova when got no servers
+* Slow down and retry aggregate create/delete to lessen race
+* Retry floating IP tests
+* Support filtering port with IP address substring
+* Fix docs from I0dc80bee3ba6ff4ec8cc3fc113b6de7807e0bf2a
+* Add ability to filter image list by tag
+* Add release note link in README
+* Change bug url to a correct one
+* Adding api\_version to FakeApp
+* Fix the \`role implies list\` command
+* Fix volume type functional tests
+* Delete the LB object quotas set command in openstackclient
+* Compute: Add description support for flavor
+* compute: limit the service's force down command above 2.10
+* Fix subnet host\_routes error
+* Do not require port argument when updating floating IP
+* Network: Add tag support for security group
+* Fix RuntimeError when showing project which has extra properties
+* Mention 2.51 in help for openstack server event show
+* Fix server show for microversion 2.47
+* Optimize \_prep\_server\_detail to avoid redundant find\_resource
+* Use Server.to\_dict() rather than Server.\_info
+* Add note about version 2.5 when listing servers using --ip6
+* Update role document to include system parameter
+* Fix urls in README.rst
+* Allow setting network-segment on subnet update
+* Add system role functionality
+* Fix lower-constraints.txt
+* Make max\_burst\_kbps option as optional for bw limit QoS rule
+* Don't display router's is\_ha and is\_distributed attributes always
+* Add cliff project link
+* Update the content about Import Format
+* Update command test for volume.v3
+* Prevent "server migrate --wait" from hanging
+* Format port\_details field of Floating IP
+* Add dns-domain support to Network object
+* Trivial: Update pypi url to new url
+* Fix functional job failed
+* Network: Add tag support for floating ip
+* Clean up W503 and E402 pep8 errors
+* Add bgp commands to neutron decoder
+* Add help for nova interface-list to decoder
+* Remove deprecated ip floating commands
+* Fix limits show command without Nova and Cinder
+
+3.15.0
+------
+
+* Updated from global requirements
+* Add --image-property parameter in 'server create'
+* add lower-constraints job
+* Rename python-openstacksdk to openstacksdk
+* Add support to list image members
+* Display private flavors in server list
+* Default --nic to 'auto' if creating a server with >= 2.37
+* Fix additional output encoding issues
+* Correct application credential usage doc
+* Fix crashing "console log show"
+* Fix typo in 'floating ip associate' command and doc
+* neutron: add --mtu for create/set network
+* Make Profile fallback go bye-bye
+* Remove duplicated network attributes
+* Re-implement novaclient bits removed in 10.0
+* Updated from global requirements
+* Update links in README
+* Imported Translations from Zanata
+* Cleanup error messages on failure
+* Update help text for encryption provider
+* Add support for endpoint group commands
+* Add support for "--dns-domain" argument
+* Add project tags functionality
+* Make osc-functional-devstack-tips actually use tips
+* Zuul: Remove project name
+* Add CRUD support for application credentials
+* Use find\_ip from openstacksdk
+* Updated from global requirements
+* Fix tox -e venv -- reno new <slug>
+* Update reno for stable/queens
+
+3.14.0
+------
+
+* Updated from global requirements
+* Fix use of new openstacksdk connection
+* Rework Network client config for new SDK Connection
+* Replace assert with condition
+* Updated from global requirements
+* Corrected spelling mistake
+* Updated from global requirements
+* Fix indentation in authentication.rst
+* Partially Revert "Update new documentation PTI jobs"
+* Use Zuul v3 fetch-subunit-output
+* Updated from global requirements
+* Updated from global requirements
+* Add floating IP qos\_policy actions
+* Updated from global requirements
+* Check that Glance returns image data before processing it
+* Allow ports filtering with device\_id
+* Update new documentation PTI jobs
+* flavor: clarify --swap description
+* Switch to use stestr directly
+* Fix func tests: Ensure to pass OS\_CLOUD envvar
+* Updated from global requirements
+
+3.13.0
+------
+
+* Send 'changes-since' instead of 'changes\_since' query parameter
+* Fix SDK Connection creation alternative to Profile
+* Make functional-tips job voting
+* Remove -U from pip install
+* openstack subnet create fails when tags is None
+* Avoid tox\_install.sh for constraints support
+* Make py27 and py35 versions and template of unit-tips jobs
+* Add cliff and keystoneauth to tips jobs
+* Remove a bunch of things we promised to remove in 2H 2017
+* Release note cleanup
+* Set correct designate endpoint in docs
+* Make osc-tox-unit-tips work on other repos
+* Allow port list to shown undefined attributes
+* Updated from global requirements
+* Fix file mode on network-topology.rst
+* Add support for endpoing filter commands
+* Remove hard-coded policy choices for creating a server group
+* Fix credentials in create, update and list
+* Remove setting of version/release from releasenotes
+* Prepare for os-clinet-config to go away
+* Add logic to handle old and new sdk constructor
+* Updated from global requirements
+* Network: Add interfaces info in router show
+* Updated from global requirements
+* Show detailed message of neutron exception
+* Add RemoveNetwork command to server
+* Replace %r with %s on printing string variable
+* Updated from global requirements
+* Neutron agent delete: remove the wrong argument
+* Display Network QoS rule type details
+* Network: Add supports rbac target-all-projects
+* Updated from global requirements
+* Rehome test units lib
+* Zuul: add file extension to playbook path
+* Add python-rsdclient into plugin list
+* Add server rescue unit tests
+* Zuul job updates
+* Add missing parameters on openstack server rescue
+* Added AddNetwork command to server
+* Convert 'server' commands to use autoprogram
+* Native DevStack jobs
+* Add wrapper around ostestr
+* Accept 0 for --min-disk and --min-ram
+* Move more jobs in-repo
+* Attempt to de-race qos policy
+* Allow creating security rules without protocol
+* Move base functional test job in-repo
+* Switch to $USER in post\_test\_hooks
+* Avoid default mutable values in arguments
+* Be robust on import plugin module
+* auto-generate docs for v3 identity resources
+* Updated from global requirements
+* Support creating unaddress neutron port
+* Optimize getting endpoint list
+* Support icmp-type and icmp-code to be set as zero
+* Fix 'project purge' deletes ALL images problem
+* Update the documentation link for doc migration
+* Updated from global requirements
+* Add "volume service list --host" functional test case
+* Add functional test cases for "volume qos associate/disassociate"
+* Unroll the network qos policy functional tests
+* Add python-zunclient plugin
+* Attempt to work around chronically failing server issues with aggregates and qos
+* Fix subunit collection in functional tests with ostestr>=1.0.0
+* Updates for stestr
+* Updated from global requirements
+* Updated from global requirements
+* Correct import of keystoneauth1 session
+* Skip Volume v1 functional tests if v1 not present
+* Fix output for subnet show
+* Useless line of code in shell.py
+* Updated from global requirements
+* Updated from global requirements
+* Update image cli doc and fix some typos
+* Updated from global requirements
+* Convert remaining network functional tests to JSON
+* Convert network qos functional tests to JSON
+* Convert network security group functional tests to JSON
+* Fix "openstack image unset" command's help message typo
+* flake8-import-order: Ensure to place project imports last
+* Implied Roles
+* Updated from global requirements
+* auto-generate object docs
+* Revert "Disable karborclient until a fixed version is released"
+* Use flake8-import-order plugin
+* Allow PD as Subnetpool during Subnet creations
+* Imported Translations from Zanata
+* Convert network segment functional tests to JSON
+* Update release/stable branch table in docs
+* Update reno for stable/pike
+* Add .htaccess for docs migration
+* Add new commands for karbor osc plugin
+* Updated from global requirements
+* Replace guildelines with guidelines
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+* network functest: Remove condition for segment test
+* Use instance variables for subnet tests
+* Skip object-store functional tests when Swift is not available
+
+3.12.0
+------
+
+* Add optional parameter "user\_id" and "type" to list credentials
+* network tag UT: avoid using mix-in test class
+* wrong values in openstack quota show command
+* Update the documentation link for doc migration
+* Network tag support
+* Updated from global requirements
+* Release note cleanup for 3.12.0
+* Updated from global requirements
+* Updated from global requirements
+* Add domain parameter to Identity Provider
+* Start using 'cliff.sphinxext'
+* Updated from global requirements
+* Clean up the changes of os.environ in functional tests
+* Minor followup to network agent docs
+* Fix dynamic names in network functional tests
+* Disable karborclient until a fixed version is released
+* Add support for virtio-forwarder VNIC type
+* Fix 'domain' filter not work well in some commands
+* Fix column names for server list --no-name-lookup
+* Updated from global requirements
+* image-list should support filters 'name','status'
+* Add 'data\_plane\_status' option to Port classes
+* Fix unit test failures related to new os-client-config and osc-lib
+* Network L3 Router Commands for OSC
+* Add server list -n and --no-name-lookup arguments
+* Use openstackdocstheme in release note
+* Add the other commands for karbor osc plugin
+* Allow objects to be streamed to stdout
+* Add new parameter "is\_default" to Network QoS policy
+* Fix man page build
+* Add missing barbican commands
+* Added 'openstack image set --visibility'
+* Add python-octaviaclient plugin
+* Remove inaccurate mapping of 'host-meta' in csv
+* Updated from global requirements
+* Updated from global requirements
+* switch to openstackdocstheme
+* Use identity auth v3 the README examples
+* Updated from global requirements
+* update the docs URLs in the readme
+* move auto-generated api docs into contributor tree
+* reorganize existing documentation according to the new standard layout
+* Enable some off-by-default checks
+* Now OSC server create check keys in --nic
+* When creating a trust, send role\_ids instead or role\_names
+* Add direction field to QoS bandwidth limit
+* Show neutron tags in OSC network show
+* Add support for Karbor Plugin
+* Add project purge command to osc
+* Don't show hint about vlan transparent in network set
+* Add default-quota to subnet pool commands
+* Updated from global requirements
+* Fix Mapping Guide Error
+* Updated from global requirements
+* volume functest: ensure snapshots deleted when volume delete
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+* Trivial fix typos
+* Replace "Display Name" by "Name" in volume list
+* JSON-ify image functional tests
+* Use \_get\_token\_resource in role assignment list
+* Updated from global requirements
+* Create server with security group ID and name
+* Refactor Extension show and list command
+* Updated from global requirements
+* Convert image functional tests into JSON format
+* Convert volume functional tests into JSON format
+* Make block-device-mapping more stable and clear
+* Correct the "extra spec" command openstack
+* Updated from global requirements
+* Ignore more exceptions in quota list
+* Rework floating ip functional tests
+
+3.11.0
+------
+
+* Do not always init compute\_client when doint port list
+* Skip floating ip attach functional test on nova-net
+* Updated from global requirements
+
+3.10.0
+------
+
+* Funcional tests: quota list
+* Nova-net functional tests: aggregates
+* Functional tests: Identity v2 and DevStack
+* Updated from global requirements
+* Fix volume qos spec list
+* Nova net functional tests round 3
+* Nova net functional tests round 2
+* Nova net functional tests round 1
+* Fix Nova-net netowrk commands
+* Fix quota functional tests for nova-net
+* Fix server create with nova-net
+* Updated from global requirements
+* Functional test for subnet\_pool
+* Fix NoneType error for volume snapshot create command
+* Improve no-auth path
+* Remove ipdb installation in tox debug section
+* Make test\_server.py more elegant and simple
+* Fix network list functional test
+* Explicitly set 'builders' option
+* Low-level Compute v2 API: floating ip pool
+* Low-level Compute v2 API: network
+* Split network tests
+* Updated from global requirements
+* Low-level Compute v2 API: floating ip
+* Low-level Compute v2 API: security group rules
+* Low-level Compute v2 API: security group
+* Add document about renaming OS\_ENDPOINT\_TYPE to OS\_INTERFACE
+* Split floating IP tests
+* Update to tox.ini
+* Add --network and --port to server create
+* Updated from global requirements
+* Split security group tests
+* Allow override of distributed router flag
+* Clean up password prompt work-arounds
+* "floating ip set/unset port" for OSC
+* Add "qos-policy" option to "port create" & "port set"
+* Structure FindFloatingIP() to work without ip\_cache
+* Enable to specify which fixed-ip to add to a vm
+* Correct flavor associate/disassociate commands in Mapping Guide
+* Help/docs cleanups: marker, limit, ip-address metavars
+* Release notes cleanup for 3.10.0 release
+* Enable to add/remove port to/from a server
+* Introduce neutron flavor associate, disassociate to OSC
+* Add help commands withouth auth in functional
+* Fix block-device-mapping when volume\_size is empty
+* Enable to create legacy router
+* Trivial Fix
+* Updated from global requirements
+* Use Sphinx 1.5 warning-is-error
+* doc: Correct Sphinx warnings
+* doc: Remove local fork of apidoc
+* Change noauth strategy for plugin loading
+* Fix volume transfers request commands
+* Doc: Fix link in network flavors
+* OSC Extension Show
+* Remove log translations
+* Fix Trivial Changes in [1]
+* Support to add/remove multi users for "group add/remove user"
+* Simplify logic around option lists in port set
+* Enable to specify which vm fixed-ip to publish
+* Introduce Neutron DHCP agent commands to OSC
+* docs: Don't include ChangeLog
+* OSC Network Flavor Profile
+* Make MAC address of port updatable
+* Non-Admin can't list own projects
+* Updated from global requirements
+* Narrow expected responses for CheckUserInGroup
+* Add extra filtering options to qos policy list
+* Adds missing flavor information in the server list long command
+* Functional test for ip\_availability
+* OSC Quota List
+* Fix reference in network flavor create command reference
+* Refactor ServerTests and ServerEventTests functional test classes
+* Fix "security group list" command to display project ID properly
+* Trivial Fix
+* Jsonify meter and meter rule functional tests
+* Revert "Fix port command for SDK >0.9.10"
+* Fix handling the use\_default\_subnet\_pool attribute
+* Add sort support to project list
+* Add the bgp agent type to network agent command
+* Remove py34 tox env and pypi classifier
+* command list: Move network meter appropriately
+* Add server event list and show commands
+
+3.9.0
+-----
+
+* Updated from global requirements
+* Cleanup release notes for 3.9.0 release
+* Trivial Fix
+* add neutron CLI to decoder
+* Normalize the gnocchiclient docs entry
+* Add "--private-key" option for "keypair create"
+* Trivial Fix
+* Updated from global requirements
+* Jsonify network flavor functional tests
+* Nit: Trivial doc formatting fix for network flavor
+* Use \*\_as\_ids instead \*\_as\_list
+* Add a validation about options for server migrate command
+* Updated from global requirements
+* Update doc/source/command-objects/image.rst
+* Port set/unset SecGroup Bug Fix
+* Fix output of ListSecurityGroupRule
+* openstack image create : --file and --volume exclude each other
+* Fix can not set is\_default in network
+* Support --no-property in "volume set" command
+* Revert unit tests for quota commands
+* Support list commands by group name keyword
+* Auto allocated topology for OSC
+* minor tweaks to mapping table
+* add keystone and glance -> osc mapping
+* Fix "endpoint list" help message
+* Show openstacksdk version info in "module list"
+* OSC Network Flavor
+* Fix properties format for volume qos in volume v1
+* Rework port functional tests on json output format
+* add volume->osc mapping
+* add swift and nova to osc mapping
+* Add Cinder v3 client support for volumes
+* TODO cleanup: osc-lib
+* Remove text about OSC as a plugin requirement
+* Remove unused logging import
+* Remove remaining uses of SDK Proxy.session
+* Finish converting server functional tests to JSON format
+* Remove quota set workaround for SDK <0.9.13
+* Fix image selection in server function tests
+* Fix "server create" command failed when --nic auto or none
+* Use public and unified method get\_console\_url()
+* Handle log message interpolation by the logger in compute/
+* Handle log message interpolation by the logger in network/
+* Handle log message interpolation by the logger in identity/
+* Updated from global requirements
+* Overwrite/Clear Flavor property
+* Refactor volume functional test in volume v1
+* Updated from global requirements
+* Updated from global requirements
+* Modify error handling for role and group commands
+* Fix --parents and --children options in project show
+* Add --fixed-ip option to the port list command
+* Fix wrong behavior of parsing plugin service name
+* Fix "module list --all" failed
+* NIT: replace os with openstack in command example
+* mention the final ocata osc version in releasenotes
+* SDK refactor: Set "is\_admin\_state\_up" for network agent
+* TODO cleanup: OSC\_Config
+* Add mitaka release notes to master
+* Update reno for stable/ocata
+
+3.8.1
+-----
+
+* Add relnotes for the two recent bug fixes
+* Fix network create --project
+* Fix address scope list --share
+
+3.8.0
+-----
+
+* Fix sphinx errors
+* Updated from global requirements
+* Cleanup for 3.8.0 release
+* Switch server create to block\_device\_mapping\_v2
+* Support "--no-property" option in volume snapshot set
+* Adds domain specification for SetUser
+* Add options to "server list" command
+* Fix Identity functional tests to not require OS\_AUTH\_URL
+* change assert\_show\_fields to not fail on new fields
+* Add server\_boot\_from\_volume() test
+* Fix 'mapping set' return value
+* Add server test for image and flavor lookups
+* Updated from global requirements
+* Use image client for images instead of compute
+* Update container format choices
+* Handle 403 error on creating trust
+* SDK refactor: Prepare security group commands
+* Add meter rule to OSC
+* Update devref about "--no-property"
+* Fix OSC networking commands help errors
+* Functional tests debug support
+* Switch to use cleanup method in functional test
+* Fix functional test for creating subnet
+* Functional test for router
+* Functional test for subnet
+* Functional test for volume qos
+* Remove the fixed set of choices for network\_type
+* Add plugin adoption for trove
+* Error in the return of command server show, create
+* Error in the return of command 'volume qos create'
+* Functional test for volume snapshot
+* Update functional test for aggregate
+* Updated from global requirements
+
+3.7.0
+-----
+
+* Release 3.7.0 cleanup
+* Fix quota set command error for SDK > 0.9.10
+* SDK refactor: Prepare network agent commands
+* Updated from global requirements
+* unskip port test
+* Use git+file urls instead of directories
+* Fix quota show --default command
+* Fix network functional tests for sdk 0.9.12
+* Fix floating IP delete and show by IP
+* Add "encryption-\*" options in volume type commands
+* Fix subnet creating failure in functional test
+* fix functional tests for network agents
+* Fix security group rule list for NEtwork v2
+* Install from /opt/stack/new instead of git.o.o
+* Fix quota show output
+* unskip network qos rule type functional test
+* Fix image member unit tests occasional failures
+* Fix flavor create help re swap size units
+* Fix Network QoS rule CLI attrs parsing
+* Add unit test for multi volume types delete
+* add support for running tests with master dependencies
+* To display image size in human friendly format
+* Updated from global requirements
+* Add support for Network QoS rule commands
+* Make 'object save' fast again
+* Fix Octavia gate breakage caused by \_get\_columns()
+* functional test for volume
+* Fix port command for SDK >0.9.10
+* Fix filter error in os volume list
+* Add --project and --project-domain option to "volume snapshot list"
+* add domain id to expected IdP fields, unskip tests
+* skip tests related to SDK 0912 and keystone IdP change
+* Functional tests - flavor
+* Add options to allow filtering on agent list
+* Fix network service provider functional test
+* Fix "ip availability show" command
+* Updated from global requirements
+* Fix creating a private flavor with ID auto
+* Functional tests - port
+* Add support for Glance 'update image members' feature
+* Fixes image api URL endpoint for certain scenario
+* Remove unneeded methods from OS\_Config class
+* Error handling for delete commands in identity
+* Update the description format
+* Add ":option:\` \`" in the help message
+* OSC Network Meter
+* Beef up floating IP functional tests
+* Beef up address scope functional tests
+* Beef up network functional tests
+* update server migrate '--wait' description
+* Revert "WIP: Skip broken functional tests..."
+* Updated from global requirements
+* Fix a spelling error
+* Fix typo in release notes
+* Add unit tests for usage commands in compute v2
+* Test-requirements.txt: Bump Hacking to 0.12
+* Updated from global requirements
+* WIP: Skip broken functional tests..
+* To support '--project' and '--project-domain' options
+* Add support for QoS rule type commands
+* Update earliest-version number format in release notes
+* Should support 'auto' and 'none' as network parameter when boot instances
+* Fix all missing "os to openstack" transformation
+* Add '--type'and other options to network rbac list
+
+3.6.0
+-----
+
+* Fix the missing os in command in example
+* Add 'allowed address pairs' option to 'port create/set/unset'
+* change os in command example to openstack(3)
+* change os in command example to openstack(2)
+* change os in command example to openstack
+* Add support for clearing router gateway
+* Introduce overwrite functionality in \`\`osc router set\`\`
+* Add one test for "backup set" command
+* Add doc for Searchlight client
+* Tivial:update the description format in volume\_snapshot.py
+* Add filtering options to the address scope list command
+* Add support for setting router gateway
+* Add ploop to supported disk formats
+* SDK refactor: Prepare network commands
+* Updated from global requirements
+* [TrivialFix] Fix typo error
+
+3.5.0
+-----
+
+* SDK Refactor: Prepare port commands
+* 3.5.0 release note cleanup
+* Updated from global requirements
+* Add two consistency group commands
+* SDK Refactor: Prepare router commands
+* Add "--remote-source" option to "volume snapshot create" command
+* update plugins documentation
+* Add extra filtering options to floating ip list
+* Correct missspellings of secret
+* Add '--force' option to 'volume snapshot delete' command
+* Modified API calls in os usage
+* Trivial: update volume-qos.rst
+* Add "consistency-group-snapshot" option to consistency group create
+* Add "consistency group set" command
+* Add --default option to "volume type list"
+* Add some options to "volume create" command
+* Revert "Remove marker and loop from "image list" command"
+* Remove auth\_with\_unscoped\_saml decorator
+* SDK Refactor: Prepare ip availability commands
+* Adjust the code sequence in consistency\_group.py
+* Avoid duplicated project\_id when show network resources
+* Add "dns-name" option to "os port create" and "os port set"
+* Add "consistency group show" command
+* Add "consistency group delete" command
+* Updated from global requirements
+* Updated from global requirements
+* Correct reraising of exception
+* Add '--project' and '--project-domain' options to os cmds
+* Add functional test for volume service
+* Add network service provider list to OSC
+* Add \`--enable/disable-port-security\` option to \`port set\` and \`port create\`
+* Add unit tests for server create in computev2
+* Trivial:modify one parameter
+* Refactor availability zone functional test
+* Add QoS support to Network object
+* Introduce overwrite functionality in \`\`osc subnet set\`\`
+* Functional test for configuration
+* Functional test for aggregate
+* Refactor module functional test
+* Add choices for option '--policy'
+* Fix description errors in volume fakes
+* DevRef fix for network qos policy
+* Add options to "volume snapshot list" command
+* Show team and repo badges on README
+* Functional test for agent
+* Add "volume host set" command
+* Updated from global requirements
+* Functional test for server group
+* clean up image choices and help text
+* Add "--type" and "--retype-policy" options to "volume set" command
+* TrivialFix in helpMessage for readability
+* Updated from global requirements
+* Add "Is Public" column in volume type list
+* Remove outdated comments in volume unit test
+* Fill the missing colon
+* Add "volume host failover" command
+* Sort list images by name by default
+* SDK Refactor: Prepare security group rule commands
+* SDK Refactor: Prepare network rbac commands
+* SDK Refactor: Prepare network qos policy commands
+* SDK Refactor: Prepare subnet commands
+* Add commands for "consistency group snapshot"
+
+3.4.1
+-----
+
+* Add relnote for release 3.4.1
+* Use project\_domain\_id only in password auth
+* Using v2 as the default version of Glance
+* Add "consistency group create" command
+
+3.4.0
+-----
+
+* translate all command help strings
+* Updated from global requirements
+* 3.4.0 release note cleanup
+* Do proper deprecation for security group rule create
+* Outdated test data clean up in volume
+* TrivialFix: Insert blank space for readability
+* Updated from global requirements
+* Updated from global requirements
+* Add '--network' and other options to floating ip list
+* Show disk format vhdx in help
+* network.common.NetworkAndComputeShowOne: catch HttpException
+* Updated from global requirements
+* Add 'description' option
+* Add 'all-projects' option to 'volume backup list'
+* Add options to "volume backup list" command
+* Updated from global requirements
+* Not appropriate name sg rule attribute
+* SDK refactor: Prepare floating ip commands
+* Refactor "snapshot" commands
+* Updated from global requirements
+* Add filtering options --name,--enable,--disable to router list
+* Support --provider-\* options in the network list command
+* Add --long option and more columns to the hypervisor list command
+* Adds information about private key generation for instance access
+* Updated coverage configuration file
+* Avoid duplicated project\_id when show network
+* Updated from global requirements
+* update openstackclient page url
+* update volume and zone commands
+* Improve a network testcase
+* Use FakeImage class to replace duplicated image info in volume test
+* Updated from global requirements
+* Correct help string of the subnet pool list options
+* Allow input the QoS policy name in network rbac create command
+* Updated from global requirements
+* Add option to allow filtering by mac-address on port list
+* Updated from global requirements
+* Warning for empty password set for user create/set
+* Reset allocation pools to [] instead of ''
+* Rename variable to avoid shadowing of built-in name
+* Add "--read-only" and "--read-write" options in "volume set"
+* Add "volume migrate" command
+* Add description field port create & port set
+* Add support make a router HA
+* Add necessary info to Floating IP list
+* properly format error messages for volume resizing
+* Updated from global requirements
+* Update the doc for Zaqar v2
+* Updated from global requirements
+* Add direction and protocol options to os security group rule list cmd
+* Updated from global requirements
+* Add a new column and a new option the 'os port list' cmd
+* Add security groups options to "port create/set/unset"
+* Fix --shared/block-migration options in server migrate command
+* Add network support for Network QoS policies
+* Fix router unset --route option
+* Redefine set/unset command devref
+* Refactor image v1 unit tests with FakeImage class
+
+3.3.0
+-----
+
+* More 3.3.0 release notes
+* Improve output of supported API versions
+* Enable release notes translation
+* Updated from global requirements
+* Mask passwords in debug logs for auth\_config\_hook
+* SDK Refactor: Prepare subnet pool commands
+* SDK Refactor: Prepare network segment commands
+* SDK Refactor: Prepare address scope commands
+* Updated from global requirements
+* Refactor qos spec unit test in volume v1
+* Add --ha option to os router create command
+* Updated from global requirements
+* Document \`openstack complete\` help and usage
+* Add example in the doc when using Identity v3
+* Updated from global requirements
+* Update default nova api version to 2.1
+* Remove beta label for network segment resource
+* Add and modify options for "volume create" command
+* Implement "consistency group list" command
+* Updated from global requirements
+* fix doc information in the limit.rst
+* Replace 'MagicMock' with 'Mock'
+* Add translation markers for object commands
+* Add option "--name" to command "openstack object create"
+* Add default limit for container/object
+* Add command option parameter in console-url.rst
+* Updated from global requirements
+* Add warning message for --state option of set command in volume
+* Align '=' for developing.rst and newton.rst
+* Updated from global requirements
+* remove square backet to required parameter
+* Remove reference to CLI Ref in osc doc
+* Add option markup in osc doc
+* Fix typo in osc doc
+* Add functional test for snapshot in volume v1
+* Support "--no" option in aggregate set
+* Updated from global requirements
+* Add --description to Neutron commands
+* Add unit tests for backup commands in volume v1
+* Use assertGreater replace assertTrue
+* Fix unset commands to pass normally when nothing specified
+* Add square bracket to option parameter
+* Updated from global requirements
+* Implement "volume transfer request show/accept" command
+* Align '=' for image.rst
+* Add "volume backup set" command in volume v2
+* Add filtering options to os network list command
+* Updated from global requirements
+* Fix "volume unset" command pass normally when nothing specified
+* Use correct router add/remove interface methods
+* Refactor volume unit test with FakeVolume class in volume v1
+* replace metavar "volume-id" with "volume" to avoid ambiguity
+* Overwrite/Clear support for subnets
+* Introduce overwrite functionality in \`\`osc port set\`\`
+* Remove unnecessary setUp
+* Add 'description' option to os subnet (pool) create/set cmd
+* Add --description to Create/Set Network
+* Clean up docs and notes for 3.3.0 release
+* Provide support to list ports by network
+* Add filtering options to os subnet pool list command
+* Add filtering options to os subnet list command
+* Fix quota-update issue in LBaaS
+* Fix Quota Support for HMs
+* Correct login name deduction in SshServer
+* router list if availability\_zone ext not enabled
+* Support mark volume as bootable in volume set
+* Doc, help and message updates for port unset
+* Replace 'MagicMock' with 'Mock'
+* Support listing specified server's ports
+* Fix openstack quota set/show --class not work
+* Support fetching network project default quota
+* Add functional tests for unset multiple volume type props
+* Set quota "per\_volume\_gigabytes", "backup\_gigabytes" and "backups"
+* Unit tests of quota command refactor
+* Trivial: Rename ListTransferRequests to ListTransferRequest
+* Display hypervisor information without uptime
+* Fix regular expression for uptime in hypervisor show
+* Add unit test for volume type in volume v1
+* Implement "volume transfer request delete" command
+* Implement "volume transfer request create" command
+* Error handling of multi REST API calls for "snapshot set" command
+* Add "--limit" and "--marker" options to "volume list" command
+* Support error handling for delete commands in volume v1
+* Multi REST API calls error handling of "volume unset" command
+* remove the old post\_test\_hook
+* remove duplicate unit test
+* unwedge the gate
+* Add network segment create, delete and set support
+* move all functional tests to tests module
+* move unit tests to new "unit" test module
+* Defer auth prompting until it is actually needed
+* standardize release note page ordering
+* Do not show "os-volume-type-access:is\_public" property of volume type
+* better functional test collection
+* format token expires time to prevent json loading datetime data
+* Update reno for stable/newton
+* Use assertIn(A, B) instead of assertTrue(A in B )
+* Updated from global requirements
+* Rearrange integration tests
+* Updated from global requirements
+
+3.2.0
+-----
+
+* Updated from global requirements
+* Add importing file to import warnings
+* Provide fallback prompt function for current osc-lib
+* Fix auth prompt brokenness
+* Updated from global requirements
+* Cleanup after install
+
+3.1.0
+-----
+
+* Fix six typos
+* Updated from global requirements
+* Clean imports in code
+* Updated from global requirements
+* Restore default auth-type for token/endpoint
+* Updated from global requirements
+* [docs] fix incorrect rst markups
+* Clean up FakeClient classes in volume fakes
+
+3.0.1
+-----
+
+* Work around a version clash issue with os-client-config
+* Fix post and periodic jobs
+
+3.0.0
+-----
+
+* Updated from global requirements
+* Add Subnet service-types to subnets
+* Integ test cleanup
+* Fix up last-minute imports to use osc-lib
+* document locale and language support tips
+* Add shell integration test
+* Gate-unbreaking combo review
+* Add "volume service set" command
+* update requirements and test requirements
+* Fix errors in volume set/unset image properties unit tests
+* Rename backup commands in volume v1 and v2
+* Add support for domain specific roles
+* Fix OSC identity v3 functional tests
+* Implement "network agent set" command
+* Add '--dhcp' and '--no-dhcp' options to os subnet list cmd
+* Add --ip-version filtering option to subnet.rst
+* Support multi REST API calls error handling for "volume set" command
+* Updated from global requirements
+* osc-lib: shell
+* Implement network agents functionality
+* Show "target\_project\_id" attribute properly for network rbac object
+* Add unit tests for group commands in identity v3
+* Updated from global requirements
+* Updated from global requirements
+* Remove an outdated directory in tox.ini
+* Add support of setting volume's state
+* Implement "network rbac set" command
+* Add a document for required options
+* Refactor identity v3 unit tests with fake class
+* Updated from global requirements
+* OS\_DEFAULT\_DOMAIN must be an ID
+* Updated from global requirements
+* Document network trunk  commands
+* Update the description of project in releasenotes
+* Updated from global requirements
+* Pass security group id to novaclient while adding security group to server
+* Implement network rbac create and delete commands
+* Allow setting quotas for server groups and server group members
+* Add support for deleting volumes with associated snapshots
+* arguments are not locale decoded into Unicode
+* Use identity fake classes instead of old unit tests data
+* Remove temporary code in ClientManager
+* Use assertEqual() instead of assertDictEqual()
+* Add options to "volume type list" command
+* Add "--marker" and "--limit" options to "snapshot list"
+* Unit test of credential in identityv3
+* Add assignment list to v2 identity and deprecate alternate listing
+* Rework clientmanager
+* Clarification of option name rules
+* Remove execute permission on a few files
+* Fix error for find\_service() in identity
+* Standardize import format
+* Remove discover from test-requirements
+* Add Support for showing flavor access list
+* Support to get server rdp/serial/mks type console url
+* Updated from global requirements
+* Set identity v3 client in networkv2 fake
+* Show project access for volume type
+* Transfer "ip floating CRUD" to "floating ip CRUD"
+* Updated from global requirements
+* Exchange the check order for the dhcp and no-dhcp
+* Support bulk deletion for delete commands in identityv3
+* Updated from global requirements
+* Unskip the tests affected by warlock 1.3.0
+* Follow upper constraints for all tox targets
+* Add create\_one\_image\_member() in FakeImage class and update test
+* Update doc for credential in indentityv3
+* Updated from global requirements
+* Allow format selection in get\_opts
+* Change to plural form of object in multi delete error message in networkv2
+* Support error handling for delete commands in volumev2
+* Make set/unset commands pass normally when nothing specified in identityv3
+* Temp work around for missing select\_auth\_plugin()
+* Add "--project" option to "volume type create" command
+* Change the wrong import order
+* Modify some help and error messages in ec2creds identityv2
+* image list: Add Checksum column
+* Add Python3.5 to setup.cfg tox.ini
+* Add "--incremental" option to "backup create" command in volume v2
+* Pass security group id to novaclient
+* Make the doc build reproducible
+* Modify compute agent set command
+* Use FakeProject and FakeDomain classes in unit tests of networkv2
+* Add missing "Volume version 2 only" message in backup.rst
+* Remove useless dest of option in volume v1&v2
+* Updated from global requirements
+* remove unused LOG
+* Updated from global requirements
+* Remove FakeService.get\_services
+* Add notes, modify notes in fakes docstring
+* Add network-topolopy support
+* Unskip tests caused by bug 1599333
+* Added a note on how to test changes
+* Correct reraising of exception
+* modify notes in the FakeHypervisorStats docstring
+* fix one spelling mistake and two help messages
+* "server list": "Image Name", "Image ID" columns
+* Add '--force' option to 'backup delete' command in volumev2
+* Add "--property" option to "snapshot create" command in volumev2
+* fix some spelling mistakes in doc/
+* skip failing tests due to bug 1599333 is fixed
+* Deduplicate get\_opts methods
+* Add python-neutronclient to OSC plugins
+* fix a few spelling mistakes
+* Remove useless dest of option in "snapshot create" command
+* Add missing '(name only)' message for keypair in computev2
+* Refactor unit tests for project and domain with fake classes in identityv3
+* Transfer "ip fixed add/remove" to "server add/remove fixed ip"
+* Transfer "ip floating add/remove" to "server add/remove  floating ip"
+* Transfer "ip floating pool list" to "floating ip pool list"
+* Updated from global requirements
+* Add command to unset information from ports
+* Add "--snapshot" option to "backup create" command in volumev2
+* update plugin documentation
+* osc-lib: api.auth
+* Add command to unset information from Subnet-pools
+* Fix doc issue for "compute agent list" command
+* Add port security option to network commands
+* Add "--property" option to "flavor create" command
+* Add command to unset information from Subnets
+* Add "--force" option to "volume qos delete" command
+* Support bulk deletion for delete commands in computev2
+* Update Fakes.py and unit tests for commands in identity V2.0
+* Modify few words and change output format for command "ip floating list"
+* skip image tag tests
+* Change "ID only" to "name or ID" for backup commands
+* Add command to unset information from Routers
+* Add "--force" option to "backup create" command in volumev2
+* Make set/unset command in volume pass normally when nothing specified
+* Modify some unusual help messages in computev2
+* Implement rbac list and show command
+* Add unit tests for "host list" and "host show" commands
+* Fix several flake8 code style issues in compute tests
+* Make code more compact for get\_list\_opts function
+* Remove code forgotten in cb28fb55884a9be7cd70c37343181116cf000a42
+* Support multi-delete for commands in identity V2
+* Fix the problem of router delete
+* Updated from global requirements
+* Improve server functional tests
+* Standardize logger usage of catalog in identity
+* Use resource id when name given for identity show
+* Fix typo in openstackclient/network/v2
+* Remove OSCGenericPassword plugin
+* Refactor unit test of "compute service list" command
+* Add FakeObject classes to fakes.py, update unit tests in identity V2
+* Fix errors for "host set" command
+* Fix token/endpoint auth plugin
+* Updated from global requirements
+* Add "--project" option to the "flavor create" command
+* Fix a missing i18n support in security\_group\_rule.py
+* Make set/unset commands in compute/image/common return normally when nothing specified
+* Improve masking of secrets in configuration show
+* Refactor setting defaults for some scope parameters
+* Refactor check\_valid\_auth\_options function
+* Make the print info support i18n
+* Support bulk deletion for "flavor/aggregate delete"
+* Add "--device-owner" option to "port list"
+* use env vars to specify OS\_IDENTITY\_API\_VERSION
+* Support JSON data for port binding profile
+* support multi-delete for volume-type
+* Standardize logger usage
+* Use osc\_lib in server\_image.py
+* Error handling of "router delete" command
+* Do not prompt for scope options with default scoped tokens
+* Updated from global requirements
+* Modify help msg and docs in identity
+* Make set/unset command in identity and image pass normally when nothing specified
+* move release note to correct directory
+* Fix console url show command broken in microversion case
+* Support bulk deletion for delete commands in networkv2
+* Add "--password-prompt" to user.rst
+* Modify doc issues about property option of aggregate
+* Add functional test for "aggregate unset" command
+* Add doc for logger usage
+* Fix help msg of identity endpoint
+* Finish osc-lib transition for command.py
+* Fix volume functional tests
+* Setup deprecate msg for command.py
+* Add default IP version and fix help messages for "ip availability list"
+* Support bulk deletion for commands that exist in both network and compute
+* Standardize logger usage in volume
+* Remove blank line in release notes
+* Add release note for network endpoint type bugfix
+* Fix missing i18n supports in api/ and shell.py
+* Fix foundation copyrights
+* Ensure endpoint type is used for network commands
+* Support compute service force down/up
+* Fix errors in \`\`set/unset flavor\`\` unit tests
+* Fix i18n problems for common files in identity
+* osc-lib: timing
+* osc-lib: command
+* osc-lib: parseractions
+* osc-lib: logs
+* osc-lib: utils
+* osc-lib: exceptions
+* Add "--network-segment" option to "subnet create"
+* Fix errors in flavor unit tests
+* Fix image delete multiple arguments error
+* Trivial: Fix coding style in examples in doc
+* Add geneve provider network type
+* Use osc-lib and set up deprecation warnings
+* Updated from global requirements
+* Moving authentication from keystoneclient to keystoneauth
+* Updated from global requirements
+* Fix network
+* Remove duplicate file logger formatter setting
+* Make set/unset commands in network return normally when nothing specified
+* Clean up fakes.py in volumev2
+* Fix compute service set command
+* Modify unit tests of compute agent delete
+* Error handling for KeyValueAction class
+* Set up 3.x release notes
+
+2.6.0
+-----
+
+* Release note cleanups for 2.6.0
+* Fix i18n supports in commom
+* Add Tox prerequisites and installation
+* Update unit test test\_extension with fake class
+* Support error handling for "port delete" command
+* Fix i18n support problems in identity
+* Add functional tests for IP availability
+* Fix release note links to (now) external docs
+* Fix errors for "volume type unset" command
+* fix keypair help msg
+* Add newline to strings in stdout/stderr.write()
+* modify server group
+* fix image unset
+* Add server set/unset unit test cases
+* Updated from global requirements
+* Add support for volume transfer request list
+* Refactor SetService --enable/disable option
+* Make set/unset commands in volume return normally when nothing specified
+* Imported Translations from Zanata
+* Add network availability for osc
+* Move server image create command to its own resource file
+* Modify the style of translated messages
+* Check port name in set port tests
+* Fix wrong test in flavor unit tests
+* Fix some missing i18n support problems in compute
+* Updated from global requirements
+* Support multiple argument for compute agent delete command
+* Update v2 endpoint show help
+* Fix --enable options on commands
+* Add support for removing flavor-access
+* Trivial: Remove duplicated line in man page
+* Updated from global requirements
+* Modify lowercase to uppercase
+* Updated from global requirements
+* Trivial: Fix i18n support in network/common.py
+* Fix unit test for volume commands in volumev2
+* include old release notes in reno
+* add unit test for compute agent command
+* Add FakeQos class and update unit test for qos\_specs in VolumeV2
+* Updated from global requirements
+* Fix i18n support in cinder
+* Add support for setting flavor-access
+* Support to set server state
+* Add "image unset" command
+* Fix output and error log in server.py
+* Support deleting multi address scopes in networkv2
+* Fix functest "test\_server\_metadata()" in test\_sever.py
+* Fix help message for "server group delete" command
+* Add network segment command object
+* [compute] Add server backup function
+* i18n support for leftover exception messages in volume
+* Do not require an scope when setting a password
+* fix endpoint show help
+
+2.5.0
+-----
+
+* keystone: fix catalog output when region is unset
+* Release notes cleanup
+* Refactor service unit tests
+* Search by user defined ID for service providers
+* Updated from global requirements
+* Fix i18n support for help and error messages in compute
+* Search by user defined ID for identity providers
+* i18n support for help and error messages in cinder
+* Add FakeType class and update volumetype test in VolumeV2
+* Add some functional tests for commands in VolumeV2
+* Updated from global requirements
+* Add FakeSnapshot class and update snapshot test in VolumeV2
+* Add functional tests for server group in ComputeV2
+* Fix image tests to use warlock resources
+* Avoid TypeError on message object additions
+* Add network support for "quota set"
+* Fix i18n support for help and log.warning in image
+* Updated from global requirements
+* Refactor TestVolumeShow with FakeVolume
+* Add FakeBackup class and updata backup unittest in volumeV2
+* Add ip version filter to subnet list
+* Added CONTRIBUTING.rst file
+* Add VLAN Transparent option to \`\`osc network\`\`
+* Fix i18n support for help and error msg in network
+* Refactor TestRemoveProjectImage with FakeImage class
+* Added --no-route to the router set command
+* Updated from global requirements
+* Changed the nomenclature of credentials command
+* Additional network protocol support
+* Refactor TestImageList with FakeImage class
+* Refactor TestAddProjectToImage with FakeImage class
+* remove #noqa from i18n imports
+* Pep8 environment to run on delta code only
+* Refactor TestVolumeList with FakeVolume
+* Fix functional test for floatingip add/remove in ComputeV2
+* Implement "address scope set" command
+* Implement "address scope show" command
+* Implement "address scope list" command
+* Implement "address scope delete" command
+* Implement "address scope create" command
+* Add unit tests for "server show" command
+* Updated from global requirements
+* Use find\_resource() instead of get() in \_prep\_server\_detail()
+* Ignore domain related config when using with keystone v2
+* Fix functional test failures
+* Map server power state num to meanful string
+* Updated from global requirements
+* Trivial: Remove unuseful comments for assertRaise() checking
+* Remove unnecessary type conversions in network unit tests
+* Ignore domain related config when using with keystone v2
+* Fix network router type display
+* bump timeout to prevent gate failures
+* Added "name" parameter to the help message
+* Add a unit test for "flavor create" command
+* Add describe of overwrite options behavior into devref
+* remove assert in favor an if/else
+* Spec to Implement IP Availability
+* Make "flavor show" command to show a private flavor properly
+* Documentation updates
+* Replace tempest-lib with tempest.lib
+* add a bandit environment to tox
+* Fix error in flavor set/unset command
+* Add functional tests for commands of floating ip
+* Fixes BadRequest when no --pool-prefix given
+* Support for volume service list
+* Doc: Add network resource descriptions
+* Devref: Command Beta
+* Support quota show for current project
+* Fix server group document issue
+* Add commands of clustering service to doc
+* Add new share and default parms to subnet pool cmds
+* Updated from global requirements
+* Fixed subnet command host route output
+* Trivial: Fix an omited i18n issue
+* Update tests for server
+* Add "server group show" command
+* Add "server group list" command
+* Add "server group delete" command
+* Add "server group create" command
+* Support X.latest format for OS\_COMPUTE\_API\_VERSION
+* Fix mutable default arguments in tests
+
+2.4.0
+-----
+
+* Rename --profile to --os-profile
+* Updated from global requirements
+* Update keypair tests
+* Fix client certificate/key support for Network v2 commands
+* Imported Translations from Zanata
+* Deduplicate CLI output parser code in test.py
+* Add provider network options to osc network set
+* Clean up for next release
+* Add options to security group rule list
+* Fix router set --route option
+* Initialize neutron client with region name
+* Updated from global requirements
+* Remove methods argument from vloume/v2/fakes.py
+* State i18() changes and help messages improved
+* Add support for removing volume-type-access
+* Fix wrong attribute name and add functional test for --snapshot
+* Remove methods argument from FakeHypervisorStats
+* Propagate AttributeErrors when lazily loading plugins
+* Add external network options to osc network set
+* Trivial: Fix incorrect comment text
+* Enhance exception handling for "network delete" command
+* Append existing information during port set
+* Use CommandFailed exception from tempest\_lib
+* Updated from global requirements
+* Fix prefixes output for subnet pool list
+* Doc: Unify repeatable option comments
+* Remove fake methods code from compute network
+* Add Testing Ref in README.rst
+* Add project options to security group rule create
+* Add network options to security group rule create
+* Add support for setting volume-type-access
+* Move keys() methods in each resource class to FakeResource
+* Add --address-scope option "subnet pool create/set"
+* Fix pep8 fail that crept in
+* use correct manager for volume snapshots
+* Fix SSL/TLS verification for network commands
+* Doc: Fix network command documentation issues
+* Append existing information during subnet set
+* TrivialFix: Rename provider segment option
+* Updated from global requirements
+* Updated from global requirements
+* Clean up release notes since 2.2.0 release
+* TrivialFix: Fix help messages for port set
+* Add option to clear information from ports
+* Make snapshot and backup name optional
+* Prefer assertEqual/assertIn over assertOutput/assertInOutput
+* Correct addCleanup use in functests
+* Support client certificate/key
+* Add provider network options to osc network create
+* Add external network options to osc network create
+* Fix typos in docstrings and comments
+* Improve tmpfile cleanup in functests
+* Remove unused method cleanup\_tmpfile
+* Use fixtures and addCleanup instead of tearDown
+* Log hint when --enable present with --disable-reason
+* Trivial: Rename FakehypervisorStats to FakeHypervisorStats
+* Add name option to 'port set'
+* rxtx factor should be a float
+* Don't mask authorization errors
+* Add default value to pool-prefix in Subnet-pool
+* Devref: Options with Multiple Values
+* Doc: Add missing command objects
+* Add --project to "subnet pool create"
+* Follow Boolean Option rule
+* Add fixed keypair create functional test
+* Fix subnet pool prefix length option
+* Wrong param type in compute-service.rst
+* Remove unused method 'from\_response'
+* Aggregate object should be "grouping of compute hosts"
+* Docs cleanup: volume command help
+* Docs cleanup: volume type
+* Docs cleanup: sort subnet commands
+* Refactor security group rule list to use SDK
+* Added functional tests for 'service provider' v3 commands
+* Add unit tests for compute v2 aggregate
+* Add "aggregate unset" to osc
+* Subnet: Add "subnet set" command using SDK
+* [Floating IP] Neutron support for "ip floating create" command
+* Support security group name for --src-group
+* Refactor security group rule create to use SDK
+* Trivial: Fix typo in common/limits.py
+* Fix "server unset" document issue
+* Use assert\_called\_once\_with() instead of assert\_called\_with()
+* Add Subnet add/remove support to router
+* Remove superfluous variable assignment statements
+* Style fix for one line docstring according to flake8
+* Add "router remove port" to osc
+* Add "router add port" to osc
+* Updated from global requirements
+* Image API v2: make volume\_type optional
+* Improve error for token issue command without auth
+* Devref: Document OSC interfaces available to plugins
+* Fix keypair create --public-key
+* Functional tests for openstackclient help messages
+* Trivial-Fix : Add a ' to the choices documentation
+* update docs with status of plugins
+* Fix options in port create/set
+* Updated from global requirements
+* Add option to allow filtering by router on port list
+* Add support for deleting Image-property
+* Add support for setting Image-property
+* Sort commands in docs
+* Doc: Fix documentation errors for command object
+* Support "--long" option in ListService
+* Use assertItemsEqual() instead of assertListEqual()
+* Trivial: Add release note for "subnet pool create" command
+* Fix dict.keys() compatibility for python 3
+* Add doc describing how to handle API errors
+* Add project options to security group create
+* Add incompatibility info for "ip floating list" command
+* Enhance list extension unit test
+* Trivial: Reorder classes in identity v3 in alphabetical order
+* Update reno for stable/mitaka
+* Add "os subnet create" command using SDK
+* Refactor security group create to use SDK
+* Refactor security group show to use SDK
+* Add subnet pool functional tests
+* Fixed command list
+* Trivial: Use 'SSH' rather than 'Ssh'
+* [Identity] Check return value is None in identity v3 unit tests
+* Add --reason for disable service
+* Remove FakeFlavorResource class
+* Add support of setting snapshot state
+* Add port functional tests
+* Add 'port set' command
+* [Subnet pool] Add 'subnet pool create' command support
+* [Subnet pool] Add 'subnet pool set' command support
+* Trivial: Fix incorrect comments in compute fakes.py
+* remove py26 workaround in osc
+* [Identity] Check return value is None in identity v3 unit tests
+* Add port list command
+* Trivial: Remove useless return
+* Use \_get\_columns() to obtain columns in network.py
+* Add release note for security group set refactor
+* Test take\_action() instead of run() in unit tests
+* Updated from global requirements
+* Add 'port create' command
+* Add subnet functional tests
+* Updated from global requirements
+* Updated from global requirements
+* " openstack server image create " doesn't print proper info
+
+2.2.0
+-----
+
+* Fix test\_aggregate functional test
+* [Volume] Check return value is None in volume unit tests
+* Fix incorrect unit test for router
+* Refactor security group set to use SDK
+* Updated from global requirements
+* Trivial: Reorder unit tests in alphabetical order in volume tests
+* [Image] Check return value is None in image unit tests
+* Support "network create" command in nova network
+* Add test cases to test some commands with '--wait' and fix bug
+* Devref: Options with Choices
+* Clean up unnecessary import of urlparse module
+* Trivial: Update image\_list v2 docs
+* Fix regression in interactive client mode
+* Fix 'code-block' tag format issues
+* TrivialOrder: Rearrange Class Names
+* add a checklist for creating a new plugin
+* Trivial: Reorder flavor op order in flavor.py
+* Subnet: Add "subnet delete" command using SDK
+* fix: Exception message includes unnecessary class args
+* Refactor security group list to use SDK
+* take\_action() method from command.Command shouldn't return
+* Trivial: Reorder unit tests in test\_type.py
+* Fix return value of "image set" command
+* [Compute] Check return value is None in compute unit tests
+* Router: Add --route and --clear-routes options to "router set" command
+* Add MultiKeyValueAction to custom parser action
+* Make SetAggregate inherit from cliff.Command
+* Make SetAgent inherit from cliff.Command
+* Make SetSecurityGroup inherit from cliff.Command
+* Make SetFlavor and UnsetFlavor inherit from cliff.Command
+* Add missing command/configuration object
+* Updated from global requirements
+* [compute] Add set host command
+* Add shell --profile option to trigger osprofiler from CLI
+* update heat object and command doc
+* Add some test cases for "server list" command
+* Floating IP: Neutron support for "ip floating show" command
+* Improve tox to show coverage report on same window
+* Py3 replace dict.iteritems with six.iteritems
+* Updated from global requirements
+* Defaults are ignored with flake8
+* Fixed a bunch of spacing
+* Add "security group rule show" command
+* Fix wrong return value in TestDeleteFloatingIPNetwork
+* Use update\_parser\_common() in ShowNetwork
+* [compute] Support restore server
+* [compute] Add unit test for keypair
+* Use instanceof instead of type
+* Add "os subnet show" command using SDK
+* Initialize \_keys in \_\_init\_\_() in FakeFlavorResource
+* Add unit tests for 'hypervisor stats' command
+* Clean redundant argument to dict.get
+* Add functional tests for "volume" commands v2
+* Add functional tests for "image" command v2
+* Updated from global requirements
+* Add unit test for "flavor show" command
+* Refactor: Set "project\_id" for FakeXXX in a consistent style
+* Fix Mutable default argument
+* gitignore .idea
+* Trivial: Rename subnet\_pool.rst to subnet-pool.rst
+* Replace string format arguments with function parameters
+* Support unscoped token request
+* Use assertIsNone() instead of assertEqual(None, xxx)
+* Don't use Mock.called\_once\_with that does not exist
+* Floating IP: Fix "ip floating list" in neutron network
+* Subnet Pool: Add "subnet pool show" command
+* Subnet Pool: Add "subnet pool list" command
+* Remove unused test-requirments
+* Subnet Pool: Add "subnet pool delete" command
+* Support "network show" command in nova network
+* Support "network list" command in nova network
+* Add release note for "network delete" command for nova network
+* Define FakeFloatingIP class in tests/compute for nova network commands
+* Add release note for "ip floating delete/list" commands for neutron network
+* Fix 'openstack --help' fails if clouds.yaml cannot be read
+* Rename parameter "identifier" to "network" in network commands
+* Use assertRaises() to check if an exception is raised
+* Support "network delete" command in nova network
+* Floating IP: Neutron support for "ip floating list" command
+* Floating IP: Neutron support for "ip floating delete" command
+* Updated from global requirements
+* Add quota functional tests
+* Add NetworkAndCompute Lister and ShowOne classes
+* Fix identity test\_role functional tests
+* Trivial: Fix a typo in test\_network.py
+* Updated from global requirements
+* Refactor network AZ exception handling
+* Refactor security group rule delete to use SDK
+* Identity: Fix DisplayCommandBase comments for cliff ShowOne subclass tests
+* Identity: Fix DisplayCommandBase comments for cliff Lister subclass tests
+* Identity: Fix DisplayCommandBase comments for cliff Command subclass tests
+* Trivial: Fix "abstractmethod" to "abstract method"
+* Fix DisplayCommandBase comments for cliff ShowOne subclass tests
+* Add "token revoke" for identity v3
+* Fix DisplayCommandBase comments for cliff Lister subclass tests
+* Fix DisplayCommandBase comments for cliff Command subclass tests
+* Updated from global requirements
+* Add release note for custom logging feature
+* Add release note for recursive delete
+* Add unit tests for "hypervisor show" command
+* Compute: Fix DisplayCommandBase comments for cliff ShowOne subclass tests
+* Compute: Fix DisplayCommandBase comments for cliff Lister subclass tests
+* Compute: Fix DisplayCommandBase comments for cliff Command subclass tests
+* Remove identity\_client.projects definition in TestSecurityGroup
+* Define security\_group\_rules mock in FakeComputev2Client
+* Move security\_groups mock definition to FakeComputev2Client
+* Fix formatting in release 2.0.0 notes
+* Fix some release note formatting
+* Add recursive object delete for containers
+* Refactor security group functional tests
+* Add functional tests for snapshots
+* Add support for triggering an crash dump
+* Add unit tests for "hypervisor list" command
+* Allow custom log levels for other loggers
+
+2.1.0
+-----
+
+* Use assert\_not\_called() in common tests
+* Minor typo in help text
+* Fix a spell typos
+* Add --marker option to "image list" command
+* Add limit option to "image list" command
+* Remove marker and loop from "image list" command
+* Trivial: Reorder test class in test\_volume.py into alphabetical order
+* Fix wrong type of volume attachments in FakeVolume
+* Refactor TestVolumeCreate to use FakeVolume
+* Refactor security group delete to use SDK
+* Add "os port show" command
+* Support listing network availability zones
+* Trivial: Fix wrong comment in test\_image.py
+* Network: Abstract get\_body() out to be a private helper
+* Drop log\_method decorator
+* Updated from global requirements
+* Consume openstackclient.common.command in subnet/port
+* Fix showing network quotas for a project
+* Add missing release notes
+* log take\_action parameters in a single place
+* Revert "Skip identity v2 functional tests"
+* Skip identity v2 functional tests
+* Add availability zone support for router commands
+* Update translation setup
+* Add availability zone support for network commands
+* Allow wait\_for\_delete to work for all clients
+* Updated from global requirements
+* Return names in list role assignments
+* Remove the Tuskar client
+* Use correct terminology for subnets
+* Updated from global requirements
+* Add releasenote for 'subnet list' command support
+* Add router functional tests
+* Subnet List
+* Updated from global requirements
+* Refactor abstract columns and datalist out in image and object test cases
+* Updated from global requirements
+* Add python-searchlightclient to list of adopters
+* Refactor abstract columns and datalist out in compute test cases
+* log\_method: get logger from decorated method if unspecified
+* Set up logger of each command by metaclass
+* Refactor: Abstract columns and datalist out in volume test cases
+* Add support to delete the ports
+* Initialize activation status
+* Imported Translations from Zanata
+* Updated from global requirements
+* Doc: Network is supported for extension object
+* Change --owner to --project in image commands
+* Support listing volume availability zones
+* Refactor "os availability zone list"
+* Changed the abstract columns and datalists from test cases of common and Identity
+* Updated from global requirements
+* Support non-interactive user password update
+* Use assertTrue/False instead of assertEqual(T/F)
+* Replace assertEqual(\*, None) with assertIsNone in tests
+* Updated from global requirements
+* Further improve output for "os security group show"
+* Delete the unused LOG configure code
+* Refactor network endpoint enablement checking
+* Implementation for project unset cmd for python-openstackclient
+* Enabling domain lookup for project set v3 command
+* Docstring should say 'default' if option is default
+* Trivial: Remove useless string\_to\_bool()
+* Refactor: Initialize parser in setUp() in TestNonNegativeAction
+* Refactor: Initialize parser in setUp() in TestKeyValueAction
+* Replace assertEqual(None, \*) with assertIsNone(\*)
+* Functional tests for security group rule
+* Improve output for "os security group show"
+* Add all regions to cloud configuration
+* Updated from global requirements
+* Add owner validation for "openstack image create/set"
+* TestServerGeneral: Add test for \_prep\_server\_detail()
+* TestServerGeneral: Add test for \_format\_servers\_list\_networks()
+* Trivial: Remove useless return from files in image and volume
+* Trivial: Remove useless return from files in network
+* Add support to list all security group rules
+* Replace assertEqual(None, \*) with assertIsNone in tests
+* Trivial: Remove useless return from files in compute
+* Add image re/deactivate commands
+* Router: Add "router show" command using SDK
+* Router: Add "router set" command using SDK
+* Refactor TestImageCreate with FakeImage class
+* Updated from global requirements
+* Router: Add "router delete" command using SDK
+* Network: Improve no option test for "network create"
+* Router: Add "router create" command using SDK
+* Remote security group name not displayed for rule
+* when fetching object store properties use lower()
+* Doc: Add optional command specs process
+* Removes MANIFEST.in as it is not needed explicitely by PBR
+* Updated from global requirements
+* Deprecated tox -downloadcache option removed
+* Router: Add "router list" command using SDK
+* Router: Add class FakeRouter to test "router xxx" command
+* Trivial: Improve unclear comments in test\_server.py
+* Make --image parameter optional in "server rebuild"
+* Trivial: Fix parameter name typo in network.rst
+* Trivial: Do not use plural format in command parameter in "network delete"
+* Map some of the SDK field names
+* TestServerGeneral: Add test for \_format\_servers\_list\_power\_state()
+* Remove python-neutronclient requirement
+* Fix poorly named test mocks
+* Remove old code after sdk integration
+* SDK integration extensions and server create networks
+* Add unit test for TestServerList to test --long option
+* Add multi deletion testcase for "openstack image delete"
+* Refactor TestImageDelete with FakeImage
+* Remove unuseful test data in test\_netwrok.py
+* Migrate network client to SDK
+* Migrate "network show" command to use SDK
+* Migrate "network set" command to use SDK
+* Migrate "network delete" command to use SDK
+* Migrate "network create" command to use SDK
+* Fix "sevice show" cannot catch NoUniqueMatch Exception
+* The format\_exc method does not take an exception
+* Migrate "network list" command to new version using SDK
+* Trivial: Coding style fix in test\_flavor.py
+* Use FakeVolume in server test cases
+* Use FakeImage in server test cases
+* Add source security group support to create rule
+* SDK integration: Add a temporary method to create network client using sdk
+* Introduce class FakeNetwork to fake one or more networks
+* Use formatter in server.py for "server list" tests
+* Updated from global requirements
+* Trivial: Import network.common as network\_common in server.py
+* Refactor network test: Remove unusful test code
+* Refactor TestShowNetwork: Use TestNetwork in TestShowNetwork
+* Refactor TestSetNetwork: Use TestNetwork in TestSetNetwork
+* Refactor TestListNetwork: Use TestNetwork in TestListNetwork
+* Refactor TestDeleteNetwork: Use TestNetwork in TestDeleteNetwork
+* Refactor TestCreateNetwork: Setup identity client in setUp() in TestCreateNetworkIdentityV2
+* Refactor TestCreateNetwork: Setup identity client in setUp() in TestCreateNetworkIdentityV3
+* Refactor TestCreateNetwork: Setup cmd in setUp() in TestCreateNetworkIdentityV2
+* Refactor TestCreateNetwork: Setup cmd in setUp() in TestCreateNetworkIdentityV3
+* Refactor TestCreateNetwork: Split TestCreateNetwork into two classes for identity v2 and v3
+* Refactor network test: Introduce TestNetworkv2 and TestNetwork to improve unit test of network
+* Trivial: Remove unuseful doc of "network list" command
+* Trivial: Improve doc for "server create" command
+* Updated from global requirements
+* Fix exception when doing volume set operation
+
+2.0.0
+-----
+
+* Trivial: Reorder doc of "server shelve" command to keep alphabetic order
+* Convert 2.0 release notes to reno format
+* Add reno for release notes management
+* Add multi deletion testcase for openstack volume delete
+* Add class TestServerList to provide basic unit test for "server list" command
+* Enable setup\_servers\_mock() to take attributes param
+* Introduce FakeImage class
+* Switch to ksa Session
+* Add release notes for 2.0.0
+* Support "server list" searching by both image name and ID
+* Support "server list" searching by both flavor name and ID
+* autodocument commands from plugins using stevedore.sphinxext
+* Remove list output from "compute service set"
+* Add --limit option to "server list" command
+* Add --marker option to "server list" command
+* Updated from global requirements
+* Add a changelog to see all changes into tagged releases
+* Integrating mistralclient with openstackclient
+* Add testcases for compute.v2.service
+* Consistency of the --all argument for snapshots
+* Introduce FakeVolume class
+* Add unit testcases for "openstack flavor delete"
+* Add project name/ID validation for "openstack quota show"
+* Add status column for "openstack image list"
+* Change the home-page value in setup.cfg
+* Remove old fake flavor data
+* Use FakeFlavor in TestServerCreate
+* User FakeFlavor in TestServerResize
+* Use FakeFlavor in TestFlavorUnset
+* Use FakeFlavor in TestFlavorSet
+* Use FakeFlavor in TestFlavorList
+* Introduce class FakeFlavor to fake one or more flavors
+* Refactor: Move FakeFlavorResource to compute\_fakes.py
+* Refactor: Abstract datalist out in TestFlavorList to avoid redundant code
+* Refactor: Abstract columns out in TestFlavorList to avoid redundant code
+* Add "openstack server unshelve" into OSC
+* Fix a bug of "openstack volume delete"
+* Use Block Storage instead of Volume
+* Add unit tests for "server stop" command
+* Add unit tests for "server start" command
+* Add unit tests for "server resume" command
+* Add unit tests for "server suspend" command
+* Add unit tests for "server unlock" command
+* Add unit tests for "server lock" command
+* Add unit tests for "server unpause" command
+* Abstract a helper function for server.xxx() tests
+* Add multiple servers test case to TestServerDelete
+* Use setup\_servers\_mock() in the base class in TestServerDelete
+* Move setup\_servers\_mock() to class TestServer
+* Trivial: Fix typo in find() in network
+* Trivial: Fix a typo
+* Change 'Object Store' to 'Object Storage'
+* Use is\_public to set access of volume type
+* Refactor: Order of security group class names
+* Move FakeServer to tests.common.v2.compute.fakes
+* Trivial: Add missing doc for parameter in wait\_for\_delete()
+* Add functional tests for network crud
+* Remove py26 support
+* Doc: Update and add IP address
+* Doc: Add security group and security group rule
+* Enable "openstack server resume" command to take multiple servers
+* Enable "openstack server suspend" command to take multiple servers
+* Add "openstack server shelve" into OSC
+* Trivial: Fix wrong doc for wait\_for\_status()
+* Updated from global requirements
+* Remove the old fake server data
+* Use class FakeServer in TestServerResize
+* Use class FakeServer in TestServerImageCreate
+* Use class FakeServer in TestServerDelete
+* Use class FakeServer in TestServerCreate
+* Add command wrapper doc
+* Trivial: Remove doc for non-existing param in format\_dict()
+* Unable to set some compute quotas
+* Add --volume to Image \`create\`
+* Have configuration tests support OCC
+* Add unit tests for "server pause" command
+* Introduce random server faking mechanism
+* Enable FakeResource to fake methods
+* Allow error status to be specified
+* Remove deprecated 'project usage list' command
+* Remove LICENSE APPENDIX
+
+1.9.0
+-----
+
+* Add release notes for 1.9.0
+* Improve "server list" command to have the same output as "nova list"
+* Enable "openstack server unlock" command to take multiple servers
+* Enable "openstack server lock" command to take multiple servers
+* Enable "openstack server unpause" command to take multiple servers
+* Add capability to update description of an IdP
+* validate non-ascii values for swift properties
+* Trivial: Fix wrong param name in comment
+* Split the vol\_id from a dev mapping
+* better format remote IDs for identity providers
+* Trivial: Fix wrong param name in comment
+* Trivial cleanup: Use plural format for "server delete" doc
+* Set default network api to 2.0 instead of 2
+* Fix the bug of "openstack console log show"
+* Enable "openstack server pause" command to take multiple servers
+* Change method to get the user\_id
+* Use fake server name instead of id when testing "server\_name" param
+* Fix a bug about "openstack server list --user"
+* Add --owner to \`image create\`
+* Trivial: Fix wrong comment of \_format\_servers\_list\_networks()
+* Add "server stop" command to osc
+* Add "server start" command to osc
+* Allow int version numbers in the clouds.yaml
+* Import the module not the class
+* Add project-name/-id validation for the OSC "openstack quota set"
+* Imported Translations from Zanata
+* Fix the bug of "openstack usage show"
+* Rename context.py to logs.py
+* Allow debug to be set in configuration file
+* Updated from global requirements
+* Trivial clean up: Add doc for "osc server lock/unlock"
+* Trivial clean up: do not use plural form in command arguments
+* Fix issue when displaying image\_member
+* Add Command Options guideline doc
+* remove url from v3 regions
+* Support pagination params for flavor list
+
+1.8.0
+-----
+
+* Add release notes for 1.8.0
+* Updated from global requirements
+* Follow-on for volume list - add tests, clean help
+* Add compute service delete
+* Add filtering by project/user for 'openstack volume list'
+* Updated from global requirements
+* Move session and fixtures to keystoneauth1
+* Remove cliff-tablib from requirements.txt
+* Updated from global requirements
+* Updated from global requirements
+* Mask the sensitive values in debug log
+* Fix functional tests for Python 3.4
+* Fix up object-store show commands
+* Change Identity API default version to 3
+* Add a table showing all the openstack plugin objects
+* unwedge the gate
+* Fix a typo in commands.rst
+* Fix typos in authentication.rst
+* Updated from global requirements
+* Add test for role list --inherited
+* Fix non-ascii issue with object commands
+* Add ID column to compute service list
+* image set should not show the resource
+* Add tags to \`image set\`
+* Clean up Image v2 image set command
+* Evaluate --inherited in role list
+* Set object store arg order in docs
+* Update the plugin docs
+* add set/unset support for objects in object store
+* add support for set/unset of container properties
+* Updated from global requirements
+* Rename swift account commands
+* Add one parenthesis
+* cleanup account ids from container commands
+* Add support for showing account details
+* Add support for updating swift account properties
+* Add tests for find\_resource()
+* Imported Translations from Zanata
+* Mark arguments for 'credential' commands as required
+* attempt to find resource by listing
+* Additional exception handling for find\_resource
+* Add shields.io version/downloads links/badges into README.rst
+* docs: pip install -e needs an argument
+* Glance \`image set\` Resolve Fracturing
+
+1.7.0
+-----
+
+* Add release notes for 1.7.0
+* Use format\_list instead of format\_dict when listing images
+* Format an images properties and tags
+* Add image create support for image v2
+* Change ignore-errors to ignore\_errors
+* Imported Translations from Zanata
+* Remove backticks from help in role commands
+* Move option logging back to start if initialize\_app()
+* Set default auth plugin back to 'password'
+* Updated from global requirements
+* Image fix bug with --volume
+* set image api to 1 for functional tests
+* Updated from global requirements
+* Use \`discover\_extensions\` for novaclient
+* Imported Translations from Transifex
+* Use novaclient.client.Client for initialization Nova client
+* Add filtering by user for 'openstack server list'
+* Add support for listing servers of other projects
+* Support listing users by group name
+* Fix compute API version snafu
+* Properly handle port arguments for ICMP
+* Use a common decorator to log 'take\_action' activation
+* Fix 'auhentication' spelling error/mistake
+* Volume v2 list does not show server name
+* Ignore flavor and image find errors on server show
+* Create log configuration class
+* default OS\_VOLUME\_API\_VERSION to v2
+* Automate flavors, networks, and image get
+* unwedge the osc gate
+* additional functional tests for identity providers
+* Adds documentation  on weekly meeting
+* Update the plugin docs for designate
+* Added note to install openstackclient
+* Override the debug default and help text
+* Running 'limits show' returns nothing
+* Optimize log formatting
+* Extract log level from configuration file
+* Move options to log level out of shell.py
+* Move set warnings filters to logging module
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+* Add tests for volume quota set
+
+1.6.0
+-----
+
+* Use correct domain to find project
+* Updated from global requirements
+* Skip functional test: test\_server\_up
+* Updated from global requirements
+* Remove non-existing hacking deviations from doc
+* Update plugin documentation
+* Set up every time record log in file
+* Add release notes for 1.6.0
+* Add developer documentation
+* Add --inherited to the role docs
+* Rename command docs to remove underscores
+* Inherited info/option when listing role assignment
+* Alphabetize setup.cfg
+* Add set feature to volume type v2
+* Add list feature to volume v2
+* Fixes inherited role assignments CRUD calls
+* Fix quota show when there is no project id
+* Add functional test for volume type create --property
+* Imported Translations from Transifex
+* Updated from global requirements
+* Added a new function test for volume type set
+* Introduce functional test for Identity Provider
+* Add domain scoping in 'role assignment list'
+* Removed unnecessary assignment of function result Joined lines together
+* New test for configuration show --mask
+* add new test for configuration show unmask
+* Minor Documentation changes for code samples
+* Set OS\_VOLUME\_API\_VERSION before running functional tests
+* Added test for \`volume type show\`
+* Add functional tests for volume type list
+* New test for configuration show
+* Imported Translations from Transifex
+* Updated from global requirements
+* Fix quota set failed problem
+* Add support for volume v2 commands
+* Add configuration show command
+* Imported Translations from Transifex
+* Add plugin interface version
+* Fix --os-auth-plugin in auth\_with\_unscoped\_saml
+* add doc for floatingip
+* Updated from global requirements
+* Fix yet more documentation warnings
+* Make trustee/trustor/project searchable by ID
+* Add create and list for volume type v2
+* add image member commands for image API
+* Fix the way auth\_type default value is overriden
+* Format volume type properties when showing
+* Rename type.py to volume\_type.py
+* Removes trailing blank in trust show
+* Add volume type show for volume v1
+* --property should be required in \`os unset\` commands
+* More minor docs fixes
+* Minor identity documentation change
+* Add functional tests server reboot
+* Add functional tests server IP attach and detach
+* Add details to the documentation
+* Making --property as required when openstack flavor unset
+* Do not set default versions in parsed args
+* Add functional tests for servers that require wait
+* Updated from global requirements
+* enhance tests for user v3
+* Remove unnecessary test extension mock
+* Remove requirements.txt from tox.ini
+* add functional tests for identity v3
+* Add functional tests for volume qos
+* Support multiple volume qos delete
+* add functional tests for identity v2
+* add --project-domain option for user v3
+* only return endpoints that have url
+* Fix the way we call find\_resource when only using ID
+* Fix image save with API v2
+* Rename endpoint type to interface
+* Updated from global requirements
+* temporarily skip help tests
+* Drop py33 support for Liberty
+* Fix interactive password prompt
+* Updated from global requirements
+* Fix wrong mock method call
+* add functional tests for identity v2
+* Fixes modules index generated by Sphinx
+* Imported Translations from Transifex
+* Fix address parsing for server ssh command
+* openstack catalog list always returns publicURL for internalURL and adminURL
+* Remove the --dhcp option to network list
+* Remove testing of cliff command line options
+* add functional tests for identity v3
+* Add --os-endpoint-type cli optional argument
+* Show which aggregate a hypervisor is member of
+* Move update code from image create command
+* Fix examples with cacert
+* Updated from global requirements
+* Add support for volume API v2 QoS commands
+* Add tests for 'list' and 'show' for volume qos v1
+* Alphabetize tests for v1 qos\_specs
+* Add docs for QoS specs
+* No need for get\_parser on QoS list
+* Alphabetize QoS specs
+* Add support for volume API v1 QoS commands
+* fix confused domain argument for network create v2
+* fix typo in network.rst
+* Updated from global requirements
+* Updated from global requirements
+* Add support to inherited project role grant calls
+* Updated from global requirements
+* fix typo for server create in server.rst
+* Fix typo in user.rst
+* Update 1.4.0 release notes
+* Refactor option handling for user|group|project domain scoping
+* Updated from global requirements
+
+1.5.0
+-----
+
+* Add release notes for 1.5.0
+* reference corect ec2 helper function
+* Add functional tests for image set
+* Updated from global requirements
+
+1.4.0
+-----
+
+* Improve the hint message
+* Fix the typo in \`openstackclient/shell.py\`
+* Add functional tests for volume set size
+* Add functional tests for server CRUD
+* Add functional tests for flavor metadata
+* Add flavor functional test
+* Add oidc plugin for listing federation projects
+* Skip trying to set project\_domain\_id if not using password
+* Updated from global requirements
+* Updated from global requirements
+* Add functional tests for security group CRUD
+* Enables retrieval of project's parents and subtree
+* Imported Translations from Transifex
+* Include links to developer workflow documentation
+* Enable specifying domain for group and role commands
+* Not use the deprecated argument
+* Add support for volume backup v2 command
+* Create 1.4.0 release notes
+* Updated from global requirements
+* Add support for volume snapshot v2 command
+* Allow --insecure to override --os-cacert
+* Clean up ec2 credentials help text
+* Add functional tests for volume set and unset
+* Add domain support for ec2creds in v3 identity
+* Add EC2 support for identity v3 API
+* Imported Translations from Transifex
+* Add a reference to the IRC channels
+* Change Credentials header to Blob from data
+* Get rid of oslo\_i18n deprecation notice
+* Fix security group list command
+* Rework shell tests
+* Add image functional tests
+* Add volume functional tests
+* Ignore cover directory from git
+* Set tenant options on parsed namespace
+* Add support for volume v2 API
+* add domain scope arguments to v3 role add in doc
+* project create is missing --parent in doc
+* add --domain argument to v3 project set
+* Add --wait to server delete
+* Use ostestr for test runs
+* Add cli tests for --verify and friends
+* Small tweaks to osc plugin docs
+* Fix shell tests
+
+1.3.0
+-----
+
+* Create 1.3.0 release notes
+* Add support for v2 image set command
+* Adds python-tuskarclient to list of plugins
+* Remove oslo serialization requirement
+* Remove oslo incubator config
+* Add missing properties to image set command
+* Add some comments about current plugin support
+* Remove checks for None dates in keypair functional tests
+* Fix client error while rescuing an instance
+* Add support for keypair functional tests
+* Fix insecure/verify options
+* Use format options for functional tests
+* Fix functional test gate
+* Updated from global requirements
+* Enable specifing domains in "role add"
+* Send the correct user-agent to Keystone
+* Updated from global requirements
+* Security group rule delete broken
+* Updated from global requirements
+* Imported Translations from Transifex
+* Don't create empty quota set requests
+* Updated from global requirements
+* Add os-client-config cli tests
+* minor syntax error in tox.ini
+* Add image show tests
+* Minor fix to openstack image show command
+
+1.2.0
+-----
+
+* Create 1.2.0 release notes
+* Fix tiny typo in comment message
+* Minor logging/debug cleanups
+* Redo 1.1.0 release notes
+* Remove unique class names because they are scoped
+* Raise exception if no session is created
+* Reduce parameters to base class execute
+* Functional tests run in many environments
+* Remove references to venv
+* Add a doc that dictates backwards incompatible changes
+* Remove run\_tests.sh
+* Security group rule create fails
+* Fix security group create description bug
+* Adds support for container selection for backup
+* Create 1.1.0 release notes
+
+1.1.0
+-----
+
+* Handle the pagination for image list
+* Refactor utility to find identity resources
+* Imported Translations from Transifex
+* remove unnecessary conditionals
+* Update the docs for new nic options
+* Begin documenting --os-cloud
+* Add --os-cloud support
+* Imported Translations from Transifex
+* Re-organize functional tests
+* Role operations should not require list object permission
+* Print warning on authentication error
+* Fix skipped image create attribute location attr
+* Uncap library requirements for liberty
+* Defer client imports
+* Better help for --nic in create server
+* Add support to specify volume quotas per volume type
+* Add docs for service provider CRUD
+* Federation Service Providers CRUD operations
+* Add warning message if unknown version supplied
+* Fix session timing
+* Add support for showing limits of a specific project
+* Suppress warnings user can't fix
+* Use glanceclient's inbuilt images find
+* Updated from global requirements
+* Imported Translations from Transifex
+* Add support to remote\_id
+* Add parent field to project creation
+* Add project and domain params to network create
+* Add a doc about authenticating against v3
+* Add the ability to set and unset flavor properties
+* Use cliff deferred help instead of homemade one
+* Base TokenEndpoint plugin on keystoneclient's
+
+1.0.3
+-----
+
+* Create 1.0.3 release notes
+* Move OSC auth plugins so they can be found
+* Add identity v3 catalog show
+* Update README
+* Imported Translations from Transifex
+* Add identity v3 catalog list
+* Fix catalog list when region name is absent
+* Add ability for diplaying hypervisor statistics
+* Add 'uptime' in 'hypervisor show'
+* Raise AttributeError for unknown attributes
+* Add hypervisor docs
+* Don't hack the image url
+* Fix embarrassing typo in man page
+* Updated from global requirements
+* Fix identity v2 catalog list
+* Fix help messages
+* Handle novaclient >2.20.0
+* Fix auth-required for help command
+* change oslo namespace to avoid warning
+* Updated from global requirements
+* Revert "Skip functional tests until they are fixed"
+* Rename --verify for server resize to avoid conflict
+* Fix error msg in sort\_items
+* Skip functional tests until they are fixed
+* Restrict groups and users from changing domains
+* Do not allow user to change domain of a project
+* Implement trust in identity v3 api
+* Imported Translations from Transifex
+* Change volume create --snapshot-id to --snapshot
+* Check volume status before extending size
+* Adding default user\_domain\_id parameter only when using password auth
+* Add sort support to image list
+* tenant\_id to project\_id in server show
+* Added capabilities/options to 'openstack flavor list' command to match capabilities already provided by 'nova flavor-list':
+* Improving the help of the lock command
+* Updated from global requirements
+* Change test order to avoid incompatibliity
+* Add network support to quota show
+* Add filter to image list
+* Add the ability to extend volumes in \`osc volume set\`
+* fix the wrong order of assertEqual args
+* Add 'find by name' to --nic for creating server
+* Remove ignore portion of tox.ini
+* fix object list command naming
+* Begin low-level API for Network v2
+* Command docs: network
+* Add region name for identity and volume clients
+* Begin low-level API for Image v1 and v2
+
+1.0.2
+-----
+
+* Fix doc building errors
+* Create 1.0.2 release notes
+* Imported Translations from Transifex
+* Add missing oslo-config to requirements
+* Update service clist commands for v2 and v3
+* Default user domain id and project domain id
+* Add helpful messages when authN'ing with password
+* Add version url config workaround
+* Use session for neutron client
+* Imported Translations from Transifex
+* Deprecate project usage list command
+* Copy wiki content to index page
+* Copy HIG from wiki
+* Tweaks to the catalog doc and show command
+* Fine tune some of the helps commands
+* Command doc: policy
+* Updated from global requirements
+* Upgrade hacking to 0.10
+* Command docs: add service
+* fix some small issues in catalog show
+* Rework role list v2 for --user and --project
+* Add versioning to the docs that missed it
+* Updated from global requirements
+* Command doc: access token
+* Request token authorize
+* Command doc: snapshot
+* Fix up snapshot command
+* Command doc: image
+* Request token creation docs + tweaks
+* Command doc: consumer
+* Allow user list to filter by project
+* Command doc: federation protocol
+* Command doc: identity provider
+* Command doc: mapping
+* Command doc: backup
+* Fixup backup list output
+* Command docs: volume
+* Update the command list
+* Command doc: volume type
+* tweak the server command docs
+* Check if service.name available before access
+* Command docs: group
+* Add endpoint v3 docs
+* Command docs: ec2 credentials
+* Rename column to \`default project id\` for long listing v3 user
+* Add missing content for token commands
+* Add docs for usage show/list
+* Command docs: flavor
+* Command docs: domain
+* Command docs: region
+* Add docs for listing availability zones
+* Bunch of formatting tweaks to server-image docs
+* type should be required for v2.0 service create
+* Command object docs: container, object
+* Catch exception when getting quota
+* Rename \`os project usage list\` to \`os usage list\`
+* Add usage show command
+* Fix a few issues with 'usage list'
+* Compute calls ignore region selection
+* add doc for group command
+* add doc for role assignment command
+* add doc for domain command
+* Allow service description to be set for KS V3
+* Revert some docs changes from multi-delete
+* add multi-delete support for identity
+* add multi-delete support for compute/image/net/volume
+* Properly format 'attached to' column list when listing volumes
+* Don't import form keystoneclient.openstack.common
+* list availability zones for compute
+* Updated from global requirements
+* Tweaks after the fact
+
+1.0.1
+-----
+
+* Release 1.0.1
+* Followup for ec2 credentials command fix
+* Fix ec2 credentials commands for new auth
+* Workflow documentation is now in infra-manual
+
+1.0.0
+-----
+
+* Command object docs: catalog, credentials, endpoint, region, token
+* Safely pop project parent id
+* Add documentation of interactive mode
+* 1.0.0 release notes
+* Command object docs: server, server image
+* Add the ability to list projects based on a user
+* Add support for domains when deleting identity v3 resources
+* Command object docs: project, role, user
+* Updated from global requirements
+* Command object docs: aggregate, console \*, keypair
+* Begin copying wiki command list here
+* Enhance the theming for modules page
+* Fix volume create --image
+* add keystone v3 region object
+* Updated from global requirements
+* Add --or-show support for v3 identity resources
+* Add authentication description doc
+* Add environment variable in the os-auth-type help
+* Liberalize version matching a bit
+* Add more session/api examples
+* Add an API example base and functional test base
+* Look harder to find DevStack
+* Add arg to 'server image create' tests
+* Add additional support for --or-show
+* Remove links from oauth consumers
+* Remove links from federation related commands in identity v3
+* cleanup files that are created for swift functional tests
+* Tests work fine with random PYTHONHASHSEED
+* Updated from global requirements
+* Swap remaining assertEqual arguments
+* Add --or-show option to user create
+* Add cliff-tablib to requirements
+* Use fixtures from keystoneclient for static data
+* Unscoped federated user-specific commands
+* Fix server create for boot-from-volume
+* Adjust some logging levels
+* Change --os-auth-plugin to --os-auth-type
+* Beef up object-store tests
+* Include support for using oslo debugger in tests
+* Clean up shell authentication
+* Fix token issue after auth changeup
+* only generate one clientmanager instance in interactive mode
+* Remove ClientManager.\_service\_catalog
+* Remove now-unnecessary client creation hacks
+* use jsonutils in oslo.serialization instead of keystoneclient
+* Close files on server create, add tests
+* Close files on image create
+* Move plugin stuff to clientmanager
+* Update use of open() in object API
+* Put pbr and six first in requirements list
+* Add plugin to support token-endpoint auth
+* Remove 'links' section from several v3 Identity objects
+* Fix issue token for v3
+* Updated from global requirements
+* Fix operation on clouds with availability-zones
+* Allow --domain to be used for identity commands without lookup
+* Add translation markers for user v2 actions
+* Add domain parameters to user show for Identity V3
+* Mark identity v2 resources for translation
+* Support for keystone auth plugins
+* Add 'command list' command
+* CRUD operations for federated protocols
+* Update for cliff commandmanager >=1.6.1
+* Update compute server messages for translation
+* Implement CRUD operations for Mapping objects
+* Fix issues with object related commands
+* Update gitignore
+* Add some code-blocks to the docs
+* Place the command to generate docs on one line
+* Remove duplicate env function in shell.py
+* Pass in domain and project as positional args, not kwargs
+* Create a whole slew of functional tests for identity
+* Add functional tests to osc
+* Move object-store commands to low-level API
+* Add low-level API base class
+* Test top-to-bottom: object-store containers
+* Updated from global requirements
+* utils.find\_resource does not catch right exception
+* Remove unused reference to keyring
+* v3 credential set always needs --user option
+* Use oslo.utils
+* Change help text for image save command
+* Fixing typo and improving docstring of find\_domain
+* Updated from global requirements
+* Acknowlege git.o.o as OpenStack's git server
+* Add service catalog commands
+* Return current user/project for user/project show commands
+* Add support for 'file' format objects
+* Add preliminary save container support
+* Add preliminary support for downloading objects
+* Stop using intersphinx
+* Updated from global requirements
+
+0.4.1
+-----
+
+* Update docs and release notes for 0.4.1 release
+* Use Keystone client session.Session
+* Add action 'user password set' for identiy v3
+* Unordered dicts and lists causes variable results
+* Leverage openstack.common.importutils for import\_class
+* Multiple args for object and container commands
+* Sync with oslo-incubator and add importutils
+* assertEquals order wrong
+* Work toward Python 3.4 support and testing
+* Make Identity client load like the others
+* Fix server add security group
+* Fix security group list for non-admin
+* Change app.restapi to app.client\_manager.session
+* Add i18n module to openstackclient
+* Create message variables for exceptions
+* Add oslo.i18n as a dependency
+* Updated from global requirements
+* Network use enable/disable vs admin state up/down
+* add service/interface/region filter for endpoint v3
+* add tests for identity v3 endpoint
+* add tests for identity v3 domain
+* a mistake in tests/identity/v3/test\_role.py
+* Add commands for object upload and delete
+* test\_find\_resource fails if run alone
+* Use oslosphinx to generate documentation
+* user create v2.0 depends on tenantId in response
+* Updated from global requirements
+* v3 endpoint set shouldn't always need service option
+* Add container create and delete support
+* Cleanup README.rst
+* fix typo in identity/v3/endpoint.py
+* Add network extension list
+* More make\_client() logging cleanup
+* Change V2 image tests to actually run V2 image code
+* Add more columns to image list output
+* Normalize more help strings
+* Fix PEP8 E302 errors
+* Fix IDP commands
+* Update help text for some network commands
+* Change object API\_NAME to 'object\_store'
+* Add Python 3 support
+* Fix server resize
+* Add basic timing support
+* Clean up make\_client() logging
+* Domain administrator cannot do project operations
+* Replaced some UTF-8 characters with ASCII characters
+* Python 3: do not compare a list to a zip object
+* Allow network find to use alternate name
+* Move network stuff to v2 instead of v2\_0
+* Catch SystemExit for parse args
+* Add support to list volume extensions
+* Python 3: remove a useless code to safe\_encode()
+* Add support to list compute extensions
+* Remove keyring support from openstackclient
+* trust authentication
+* Python 3: do not use \_\_builtin\_\_
+* Updated from global requirements
+* Remove backslash usage from a few tests
+* Sort/clean setup.cfg
+* Rename token classes to match command
+* Fix PEP8 E126 and E202 errors
+* Fix PEP8 E265 errors
+* Fix PEP8 H405 errors
+* Fixed typos in the identity client
+* Network CRUD
+* Updated from global requirements
+* sync oslo bits
+
+0.4.0
+-----
+
+* Update docs and release notes for 0.4.0
+* Updated from global requirements
+* Complete Identity v3 list command filters
+* Change the token verb to issue/revoke
+* Update docs template
+* Add a docs job to tox.ini
+* Fix find\_resource for keystone and cinder
+* Image create and set command updates and tests
+* Refactor oauth1 code for updates
+* Updated from global requirements
+* Clean up logging levels
+* Ignore most of the new hacking 0.9.2 rules
+* Refactor role list subcommand for identity v3 api
+* Add support for extension list
+* Add role assignments list support to identity v3
+* Add token delete command for identity v2
+* Fixed several typos throughout the codebase
+* replace string format arguments with function parameters
+* Add tests for identity endpoints
+* Change volume create --volume-type to --type
+* Fix server image create
+* Display all server log when --lines option is None
+* Fix help message for \`ip floating delete\`
+* volume type create should display properties
+* Skip auth in cinderclient
+* Updated from global requirements
+* Implement CRUD operations for Identity Providers
+* Updated from global requirements
+* move read\_blob\_file\_contents to utils
+* Pass arguments to v3 keystoneclient by kwarg
+* Fix the project option to user list so it filters
+* Make endpoint commands more consistent
+* Correct display of project/tenant id on display of credentials
+* Produce a useful error message for NoUniqueMatch
+* identity v3 allow project list filtering by domain
+* Updated from global requirements
+* Fix 'keypair show' command output
+* add interface and url to endpoint list
+* Fixed spelling error, compatability to compatibility
+* Fixed Spelling errors - compatability to compatibility
+* Fixed spelling errors - occurance to occurence
+* Make bash comple command best effort to authorize
+* Add ability to set key value pairs in projects
+* Updated from global requirements
+* Add --volume option to image create command
+* Update release notes for 0.3.1
+* In anticipation of network agents, rename compute
+
+0.3.1
+-----
+
+* Use cacert values when creating identity client
+* Updated from global requirements
+* Fix volume commands with multiple regions
+* Add ability to prompt for passwords for user create and set
+* Fix some help strings
+* Fix format errors in nova security group rule list
+* Update oslo incubator bits
+* Python 3: the content of a FakeResponse must be bytes
+* Rename Openstack to OpenStack
+* FakeResponse: use a default status code
+* Python 3: fix a syntax error
+* Use six.iteritems() rather than dict.iteritems()
+* Remove tox locale overrides
+* Glance client no longer isa http client
+* Fix misspellings in python openstackclient
+* Add token create subcommand for identity v3 api
+* Updated from global requirements
+* Fix keyring issue where there were name space problems
+* Remove remaining print statements
+* Remove copyright from empty files
+* Add token create subcommand for identity v2 api
+* Sync with global requirements
+* Fix errant underscores
+* Add support for specifying custom domains
+* Fix image set properties error
+* Displaying curl commands for nova and cinder calls
+* Closes-Bug: #1262322 Make links clickable
+* Closes-Bug: #1262321 Remove the unimplemented post\_process method call
+
+0.3.0
+-----
+
+* Release notes for 0.3.0 release
+* Remove mox3 requirement
+* Updated from global requirements
+* Update docs for plugins and release notes
+* Add missing requests and six requirements
+* Add module list command
+* Update OSC's CommandManager subclass
+* Bring RESTApi closer to ithe imminent keystoneclient.Session
+* Add return Closes-Bug: 1246356
+* Restore Object API name 'object-store'
+* Expand support for command extensions
+* Fix typo
+* Support building wheels (PEP-427)
+* Add server image create command
+* Complete basic test infrastructure
+* change execute to run
+* Update URL for global hacking doc and fix typos
+* Remove httpretty from test requirements
+* Updated from global requirements
+* Do lookups for user, project in volume create
+* Adjust to non-deprecated names in Keyring 1.6.+
+* Updated from global requirements
+* Sync oslo-incubator for py33 fixes
+* Add options to support TLS certificate verification
+* Updated from global requirements
+* Add object-store show commands
+
+0.2.2
+-----
+
+* Update release notes for 0.2.2
+* Sort entrypoints in setup.cfg
+* Fix security group entrypoints
+* Delay authentication to handle commands that do not require it
+* Identity v3 tests
+* Prepare for Identity v3 tests
+* Add to clientmanager tests
+* Add Identity v2 role and service tests
+* Refactor fake data for projects and users
+* Update tox.ini for new tox 1.6 config
+* Update requirements.txt and test-requirements.txt
+* Object API commands using our REST API layer
+* Create a new base REST API interface
+* Re-order oauth commands and sync with keystoneclient
+* Add Identity v2 user tests
+* Add Identity v2 project tests
+* Updated from global requirements
+
+0.2.1
+-----
+
+* Add release notes in docs
+* Sync with global requirements
+
+0.2.0
+-----
+
+* Change version reporting to use pbr
+* Modify run\_tests.sh to just run tox
+
+0.2.rc1
+-------
+
+* Prep for 0.2 release (0.2.rc1)
+
+0.2.alpha1
+----------
+
+* Remove 'oauth authorization show' function from identity v3
+* Remove tenant round 3 - other commands
+* Remove tenant round 2 - Identity API
+* Remove tenant round 1 - global options
+* Add server ssh command
+* Begin Python 3 compatability
+* Add security group commands
+* Add server resize command
+* Add server migrate command
+* Add server commands: (un)lock, (un)rescue, (un)set, add/remove volume
+* Add usage command for compute api
+* Add server diagnose for compute api
+* Fix --password in server rebuild
+* Change volume manager to volume type, unset property for type
+* Clean up properties (metadata) formatting
+* Add password field to set user
+* Add aggregate commands
+* Complete Image v1
+* Add quota commands
+* Add list and delete authorizations for oauth commands
+* Add --catalog to service show
+* Update openstack-common.conf format
+* Add show limits command
+* Remove api = apiName calls from each method
+* Add authenticate method to oauth code
+* Sync install\_venv\_common from oslo
+* Update documentation with info about setup.cfg
+* Add EC2 credentials CRUD
+* Finish up v3 role commands
+* Add methods for user and group interactions
+* Move tests into project package
+* Remove python3 incompatible exception syntax
+* Add OAuth support for Identity V3
+* Fix py26 tests: assertDictEqual
+* Remove explicit distribute depend
+* Add volume backup commands
+* python3: Introduce py33 to tox.ini
+* Rename requires files to standard names
+* Fix identity v2.0 entry point
+* Tweak volume commands and add k=v argparse action
+* Add domain and description to user for v3 identity
+* Migrate to pbr
+* Migrate to flake8
+* Fix flake8 errors in anticipation of flake8 patch
+* Rename all instances of 'metadata' to 'property'
+* Switch to noun-verb command forms
+* Add console commands
+* Adds image \`create\` and \`delete\` functionality
+* Add fixed-ip and floating-ip commands
+* Add compute keypair commands
+* metadata is one word
+* Add policy to identity v3
+* Add metadata support for volume
+* Make entry point strings readable
+* Add extra-specs support for volume-type
+* Add endpoint v3 functionality
+* Add service v3 support for identity
+* Add functionality for add-role commands
+* Add a simple extension hook
+* Removed unused imports
+* Add role v3 support to identity in openstack client
+* Added compute hypervisor support
+* Add optional arguments to volume list command
+* Turn down requests logging level
+* Add force-delete option for volumes
+* Add snapshot support for v1 volume
+* add domain, credential to identity v3 api
+* Add volume support for openstack client
+* Add compute hosts support
+* Clean up args and help strings in server commands
+* Change create flavor to use default arguments
+* Add metadata support for volume type
+* Added compute service support
+* Add quota v1 support for volume
+* Added compute flavor support
+* Remove underscore
+* Added compute agent support
+* Correct the version mapping to image service
+* Add volume test cases and structure
+* Add Cinder API V1 Support
+* Multiple API version support
+* Update .coveragerc
+* Sync latest openstack-common
+* Upgraded to PEP8 1.3.3 to stay aligned with Nova, etc
+* Copy cfg and iniparser from oslo-incubator
+* Clean up test\_shell so that the tests are captured though the test framework
+* Remove old/unsupported options from run\_tests help message
+* Use install\_venv\_common.py from oslo
+* Updated README to reflect latest changes
+* Ensure that image and identity clients are constructed properly
+* First pass at adding compute unit tests
+* v3 identity - group and project api
+* Fix test runner run\_tests.sh is broken
+* Use the cliff framework's ShowOne as intended for \`show image\`
+* Sync latest openstack-common updates
+* Standardize on a copyright header and ensure all files have them
+* Remove incorrect 'raise'
+* Migrate from nose to testr
+* Clean up test environment and remove unused imports
+* Updated gitignore and manifest
+* Adds Glance API v2 support
+* Move from unittest2 to testtools
+* Increment minimum required keystoneclient version number
+* bug 1091029
+* Remove upper bounds on openstack dependencies
+* Fixes setup compatibility issue on Windows
+* Add OpenStack trove classifier for PyPI
+* Add cliff prereqs
+* Update compute client bits
+* Fix PEP8 issues
+* Document the use of keyring
+* Add nosehtmloutput as a test dependency
+* Keyring support for openstackclient
+* Secure password prompt (docs)
+* Use PyPI for client libs
+* If no password in env or command line, try prompting
+* Add read\_versioninfo method
+* Fixed a typo in the rst docs
+* Add post-tag versioning
+* Update Contributing blurb in the docs
+* Create tests for shell interface
+* Refactor cliff.Command.run()
+* Fix pep8 issues
+* Move docs to doc
+* minor fixes
+* removing print call in roles get\_data
+* Documented python setup.py develop
+* Fix 'set user' command
+* Add role CRUD commands
+* Add endpoint CRUD commands
+* Added :: to readme.rst to format correctly
+* Clean up tenant and server
+* Added conf.py so Sphinx docs will build
+* Document how to install the client
+* Moved test related packages to test-requires
+* Update service commands
+* Add user CRUD commands
+* Updating Readme Document
+* correcting ordering of imports
+* fix authentication setup in interactive mode and improve error handling so tracebacks are not printed twice
+* Revise command boolean flags
+* Move get\_client\_class() to common.utils
+* Add tenant CRUD commands
+* Add API versioning support
+* look at the command the user is going to run before trying to authenticate them
+* Add copyright notices and update dates
+* Add tenant commands, work on service
+* More identity client config
+* Remove printt
+* Add Identity to ClientManager
+* Fix "help" command and implement "list server" and "show server"
+* Adding HACKING doc to project
+* Change binary name to 'openstack'
+* Auto generate AUTHORS for python-openstackclient
+* Adding name to Authors and updating a bad URL.  More to get my gerrit workflow up
+* Shell init & logging
+
+0.1
+---
+
+* Reset project version to 0.1
+* Add openstack-common and test infrastructure
+* Cleanup auth client path
+* Add 'list service' command and common modules
+* Add token auth to shell and README
+* Begin to add Keystone auth
+* Change to argparse to match cliff 0.2
+* Clean up command output
+* Use cliff
+* Set up common utils
+* Add openstackclient bits
+* First commit
diff -pruN 7.4.0-3/Dockerfile 8.1.0+git2025070715.9d3a956a-0ubuntu2/Dockerfile
--- 7.4.0-3/Dockerfile	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/Dockerfile	2025-07-07 22:41:56.000000000 +0000
@@ -13,12 +13,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM docker.io/opendevorg/python-builder:3.11-bookworm as builder
+FROM docker.io/opendevorg/python-builder:3.12-bookworm AS builder
 
 COPY . /tmp/src
 RUN assemble
 
-FROM docker.io/opendevorg/python-base:3.11-bookworm
+FROM docker.io/opendevorg/python-base:3.12-bookworm
+
+LABEL org.opencontainers.image.title="python-openstackclient"
+LABEL org.opencontainers.image.description="Client for OpenStack services."
+LABEL org.opencontainers.image.licenses="Apache License 2.0"
+LABEL org.opencontainers.image.url="https://www.openstack.org/"
+LABEL org.opencontainers.image.documentation="https://docs.openstack.org/python-openstackclient/latest/"
+LABEL org.opencontainers.image.source="https://opendev.org/openstack/python-openstackclient"
 
 COPY --from=builder /output/ /output
 RUN /output/install-from-bindep
diff -pruN 7.4.0-3/PKG-INFO 8.1.0+git2025070715.9d3a956a-0ubuntu2/PKG-INFO
--- 7.4.0-3/PKG-INFO	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/PKG-INFO	2025-07-07 22:42:17.978110300 +0000
@@ -0,0 +1,264 @@
+Metadata-Version: 2.2
+Name: python-openstackclient
+Version: 8.1.1.dev14
+Summary: OpenStack Command-line Client
+Author-email: OpenStack <openstack-discuss@lists.openstack.org>
+License: Apache-2.0
+Project-URL: Homepage, https://docs.openstack.org/python-openstackclient/
+Project-URL: Repository, https://opendev.org/openstack/python-openstackclient/
+Classifier: Environment :: OpenStack
+Classifier: Intended Audience :: Information Technology
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Requires-Python: >=3.10
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+Requires-Dist: pbr!=2.1.0,>=2.0.0
+Requires-Dist: cryptography>=2.7
+Requires-Dist: cliff>=4.8.0
+Requires-Dist: iso8601>=0.1.11
+Requires-Dist: openstacksdk>=4.5.0
+Requires-Dist: osc-lib>=2.3.0
+Requires-Dist: oslo.i18n>=3.15.3
+Requires-Dist: python-keystoneclient>=3.22.0
+Requires-Dist: python-cinderclient>=3.3.0
+Requires-Dist: requests>=2.27.0
+Requires-Dist: stevedore>=2.0.1
+Dynamic: requires-dist
+
+===============
+OpenStackClient
+===============
+
+.. image:: https://img.shields.io/pypi/v/python-openstackclient.svg
+    :target: https://pypi.org/project/python-openstackclient/
+    :alt: Latest Version
+
+OpenStackClient (OSC) is a command-line client for OpenStack that brings
+the command set for Compute, Identity, Image, Network, Object Store and Block
+Storage APIs together in a single shell with a uniform command structure.
+Support for additional service APIs is provided via plugins.
+
+The primary goal is to provide a unified shell command structure and a common
+language to describe operations in OpenStack.
+
+Getting Started
+===============
+
+OpenStack Client can be installed from PyPI using pip:
+
+.. code-block:: shell
+
+    python3 -m pip install python-openstackclient
+
+You can use ``--help`` or the ``help`` command to get a list of global options
+and supported commands:
+
+.. code-block:: shell
+
+    openstack --help
+    openstack help
+
+You can also get help for a specific command:
+
+.. code-block:: shell
+
+    openstack server create --help
+    openstack help server create
+
+You can add support for additional services by installing their clients. For
+example, to add support for the DNS service (designate):
+
+.. code-block:: shell
+
+    python3 -m pip install python3-designateclient
+
+A ``Dockerfile`` is provided for your convenience in the repository. You can
+use this to build your own container images:
+
+.. code-block:: shell
+
+    git clone https://opendev.org/openstack/python-openstackclient
+    cd python-openstackclient
+    podman build . -t example.com/myuser/openstackclient
+
+For more information the available options and commands, refer to the `Users
+Guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/cli/index.html
+
+Configuration
+=============
+
+OpenStack Client must be configured with authentication information in order to
+communicate with a given OpenStack cloud. This configuration can be achieved
+via a ``clouds.yaml`` file, a set of environment variables (often shared via an
+``openrc`` file), a set of command-line options, or a combination of all three.
+Your cloud provider or deployment tooling will typically provide either a
+``clouds.yaml`` file or ``openrc`` file for you. If using a ``clouds.yaml``
+file, OpenStack Client expects to find it in one of the following locations:
+
+* If set, the path indicated by the ``OS_CLIENT_CONFIG_FILE`` environment
+  variable
+* ``.`` (the current directory)
+* ``$HOME/.config/openstack``
+* ``/etc/openstack``
+
+The options you should set will depend on the configuration of your cloud and
+the authentication mechanism(s) supported. For example, consider a cloud that
+supports username/password authentication. Configuration for this cloud using a
+``clouds.yaml`` file would look like so:
+
+.. code-block:: yaml
+
+    clouds:
+      my-cloud:
+        auth:
+          auth_url: '<url-to-openstack-identity>'
+          project_name: '<project-name>'
+          project_domain_name: '<project-domain-name>'
+          username: '<username>'
+          user_domain_name: '<user-domain-name>'
+          password: '<password>'  # (optional)
+        region_name: '<region>'
+
+The corresponding environment variables would look very similar:
+
+.. code-block:: shell
+
+    export OS_AUTH_URL=<url-to-openstack-identity>
+    export OS_REGION_NAME=<region>
+    export OS_PROJECT_NAME=<project-name>
+    export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+    export OS_USERNAME=<username>
+    export OS_USER_DOMAIN_NAME=<user-domain-name>
+    export OS_PASSWORD=<password>  # (optional)
+
+Likewise, the corresponding command-line options would look very similar:
+
+::
+
+    openstack
+    --os-auth-url <url-to-openstack-identity>
+    --os-region <region>
+    --os-project-name <project-name>
+    --os-project-domain-name <project-domain-name>
+    --os-username <username>
+    --os-user-domain-name <user-domain-name>
+    [--os-password <password>]
+
+.. note::
+
+    If a password is not provided above (in plaintext), you will be
+    interactively prompted to provide one securely.
+
+Some clouds use federated authentication. If this is the case, your
+configuration will be slightly more involved. For example, to configure
+username/password authentication for a federated user using a ``clouds.yaml``
+file:
+
+.. code-block:: yaml
+
+    clouds:
+      my-cloud:
+        auth:
+          auth_url: '<url-to-openstack-identity>'
+          project_name: '<project-name>'
+          project_domain_name: '<project-domain-name>'
+          username: '<username-in-idp>'
+          user_domain_name: '<user-domain-name>'
+          password: '<password-in-idp>'
+          identity_provider: '<the-desired-idp-in-keystone>'
+          client_id: '<the-client-id-configured-in-the-idp>'
+          client_secret: '<the-client-secret-configured-in-the-idp>'
+          openid_scope: '<the-scopes-of-desired-attributes-to-claim-from-idp>'
+          protocol: '<the-protocol-used-in-the-apache2-oidc-proxy>'
+          access_token_type: '<the-access-token-type-used-by-your-idp>'
+          discovery_endpoint: '<the-well-known-endpoint-of-the-idp>'
+        auth_type: 'v3oidcpassword'
+        region_name: '<region>'
+
+The corresponding environment variables would look very similar:
+
+.. code-block:: shell
+
+    export OS_PROJECT_NAME=<project-name>
+    export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+    export OS_AUTH_URL=<url-to-openstack-identity>
+    export OS_IDENTITY_API_VERSION=3
+    export OS_AUTH_TYPE=v3oidcpassword
+    export OS_USERNAME=<username-in-idp>
+    export OS_PASSWORD=<password-in-idp>
+    export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone>
+    export OS_CLIENT_ID=<the-client-id-configured-in-the-idp>
+    export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp>
+    export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp>
+    export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy>
+    export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
+    export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
+
+Likewise, the corresponding command-line options would look very similar:
+
+.. code-block:: shell
+
+    --os-project-name <project-name>
+    --os-project-domain-name <project-domain-name>
+    --os-auth-url <url-to-openstack-identity>
+    --os-identity-api-version 3
+    --os-auth-plugin openid
+    --os-auth-type v3oidcpassword
+    --os-username <username-in-idp>
+    --os-password <password-in-idp>
+    --os-identity-provider <the-desired-idp-in-keystone>
+    --os-client-id <the-client-id-configured-in-the-idp>
+    --os-client-secret <the-client-secred-configured-in-the-idp>
+    --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp>
+    --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy>
+    --os-access-token-type <the-access-token-type-used-by-your-idp>
+    --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
+
+For more information on configuring authentication, including an overview of
+the many authentication mechanisms supported, refer to the `Authentication
+guide`__. For more information on configuration in general, refer to the
+`Configuration guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
+.. __: https://docs.openstack.org/python-openstackclient/latest/configuration/index.html
+
+Contributing
+============
+
+You can clone the repository from opendev.org::
+
+    git clone https://opendev.org/openstack/python-openstackclient
+    cd python-openstackclient
+
+OpenStack Client uses the same contributor process as other OpenStack projects.
+For information on this process, including help on setting up you Gerrit
+account and an overview of the CI process, refer to the `OpenStack Contributors
+Guide`__.
+
+For more information on contributing to OpenStack Client itself, including
+guidance on how to design new commands and how to report bugs, refer to the
+`Contributors Guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/contributor/index.html
+.. __: https://docs.opendev.org/opendev/infra-manual/latest/developers.html
+
+Links
+-----
+
+* `Issue Tracker <https://bugs.launchpad.net/python-openstackclient>`_
+* `Code Review <https://review.opendev.org/#/q/status:open+project:openstack/openstacksdk,n,z>`_
+* `Documentation <https://docs.openstack.org/python-openstackclient/latest/>`_
+* `PyPi <https://pypi.org/project/python-openstackclient>`_
+* `Mailing list <https://lists.openstack.org/mailman3/lists/openstack-discuss.lists.openstack.org/>`_
+* `Release Notes <https://docs.openstack.org/releasenotes/python-openstackclient>`_
+* `IRC (#openstack-sdks on OFTC (irc.oftc.net)) <irc://irc.oftc.net/openstack-sdks>`_
diff -pruN 7.4.0-3/README.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/README.rst
--- 7.4.0-3/README.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/README.rst	2025-07-07 22:41:56.000000000 +0000
@@ -1,12 +1,3 @@
-========================
-Team and repository tags
-========================
-
-.. image:: https://governance.openstack.org/tc/badges/python-openstackclient.svg
-    :target: https://governance.openstack.org/tc/reference/tags/index.html
-
-.. Change things from this point on
-
 ===============
 OpenStackClient
 ===============
@@ -15,96 +6,158 @@ OpenStackClient
     :target: https://pypi.org/project/python-openstackclient/
     :alt: Latest Version
 
-OpenStackClient (aka OSC) is a command-line client for OpenStack that brings
+OpenStackClient (OSC) is a command-line client for OpenStack that brings
 the command set for Compute, Identity, Image, Network, Object Store and Block
 Storage APIs together in a single shell with a uniform command structure.
+Support for additional service APIs is provided via plugins.
 
 The primary goal is to provide a unified shell command structure and a common
 language to describe operations in OpenStack.
 
-* `PyPi`_ - package installation
-* `Online Documentation`_
-* `Launchpad project`_ - bugs and feature requests
-* `Blueprints`_ - feature specifications (historical only)
-* `Source`_
-* `Developer`_ - getting started as a developer
-* `Contributing`_ - contributing code
-* `Testing`_ - testing code
-* IRC: #openstack-sdks on OFTC (irc.oftc.net)
-* License: Apache 2.0
-
-.. _PyPi: https://pypi.org/project/python-openstackclient
-.. _Online Documentation: https://docs.openstack.org/python-openstackclient/latest/
-.. _Blueprints: https://blueprints.launchpad.net/python-openstackclient
-.. _`Launchpad project`: https://bugs.launchpad.net/python-openstackclient
-.. _Source: https://opendev.org/openstack/python-openstackclient
-.. _Developer: https://docs.openstack.org/project-team-guide/project-setup/python.html
-.. _Contributing: https://docs.openstack.org/infra/manual/developers.html
-.. _Testing: https://docs.openstack.org/python-openstackclient/latest/contributor/developing.html#testing
-.. _Release Notes: https://docs.openstack.org/releasenotes/python-openstackclient
-
 Getting Started
 ===============
 
-OpenStack Client can be installed from PyPI using pip::
+OpenStack Client can be installed from PyPI using pip:
 
-    pip install python-openstackclient
+.. code-block:: shell
 
-There are a few variants on getting help.  A list of global options and supported
-commands is shown with ``--help``::
+    python3 -m pip install python-openstackclient
 
-   openstack --help
+You can use ``--help`` or the ``help`` command to get a list of global options
+and supported commands:
 
-There is also a ``help`` command that can be used to get help text for a specific
-command::
+.. code-block:: shell
 
+    openstack --help
     openstack help
+
+You can also get help for a specific command:
+
+.. code-block:: shell
+
+    openstack server create --help
     openstack help server create
 
-If you want to make changes to the OpenStackClient for testing and contribution,
-make any changes and then run::
+You can add support for additional services by installing their clients. For
+example, to add support for the DNS service (designate):
+
+.. code-block:: shell
+
+    python3 -m pip install python3-designateclient
+
+A ``Dockerfile`` is provided for your convenience in the repository. You can
+use this to build your own container images:
 
-    python setup.py develop
+.. code-block:: shell
 
-or::
+    git clone https://opendev.org/openstack/python-openstackclient
+    cd python-openstackclient
+    podman build . -t example.com/myuser/openstackclient
 
-    pip install -e .
+For more information the available options and commands, refer to the `Users
+Guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/cli/index.html
 
 Configuration
 =============
 
-The CLI is configured via environment variables and command-line
-options as listed in  https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
+OpenStack Client must be configured with authentication information in order to
+communicate with a given OpenStack cloud. This configuration can be achieved
+via a ``clouds.yaml`` file, a set of environment variables (often shared via an
+``openrc`` file), a set of command-line options, or a combination of all three.
+Your cloud provider or deployment tooling will typically provide either a
+``clouds.yaml`` file or ``openrc`` file for you. If using a ``clouds.yaml``
+file, OpenStack Client expects to find it in one of the following locations:
+
+* If set, the path indicated by the ``OS_CLIENT_CONFIG_FILE`` environment
+  variable
+* ``.`` (the current directory)
+* ``$HOME/.config/openstack``
+* ``/etc/openstack``
+
+The options you should set will depend on the configuration of your cloud and
+the authentication mechanism(s) supported. For example, consider a cloud that
+supports username/password authentication. Configuration for this cloud using a
+``clouds.yaml`` file would look like so:
+
+.. code-block:: yaml
+
+    clouds:
+      my-cloud:
+        auth:
+          auth_url: '<url-to-openstack-identity>'
+          project_name: '<project-name>'
+          project_domain_name: '<project-domain-name>'
+          username: '<username>'
+          user_domain_name: '<user-domain-name>'
+          password: '<password>'  # (optional)
+        region_name: '<region>'
 
-Authentication using username/password is most commonly used:
+The corresponding environment variables would look very similar:
 
-- For a local user, your configuration will look like the one below::
+.. code-block:: shell
 
     export OS_AUTH_URL=<url-to-openstack-identity>
-    export OS_IDENTITY_API_VERSION=3
+    export OS_REGION_NAME=<region>
     export OS_PROJECT_NAME=<project-name>
     export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
     export OS_USERNAME=<username>
     export OS_USER_DOMAIN_NAME=<user-domain-name>
     export OS_PASSWORD=<password>  # (optional)
 
-  The corresponding command-line options look very similar::
+Likewise, the corresponding command-line options would look very similar:
 
-    --os-auth-url <url>
-    --os-identity-api-version 3
+::
+
+    openstack
+    --os-auth-url <url-to-openstack-identity>
+    --os-region <region>
     --os-project-name <project-name>
     --os-project-domain-name <project-domain-name>
     --os-username <username>
     --os-user-domain-name <user-domain-name>
     [--os-password <password>]
 
-- For a federated user, your configuration will look the so::
+.. note::
+
+    If a password is not provided above (in plaintext), you will be
+    interactively prompted to provide one securely.
+
+Some clouds use federated authentication. If this is the case, your
+configuration will be slightly more involved. For example, to configure
+username/password authentication for a federated user using a ``clouds.yaml``
+file:
+
+.. code-block:: yaml
+
+    clouds:
+      my-cloud:
+        auth:
+          auth_url: '<url-to-openstack-identity>'
+          project_name: '<project-name>'
+          project_domain_name: '<project-domain-name>'
+          username: '<username-in-idp>'
+          user_domain_name: '<user-domain-name>'
+          password: '<password-in-idp>'
+          identity_provider: '<the-desired-idp-in-keystone>'
+          client_id: '<the-client-id-configured-in-the-idp>'
+          client_secret: '<the-client-secret-configured-in-the-idp>'
+          openid_scope: '<the-scopes-of-desired-attributes-to-claim-from-idp>'
+          protocol: '<the-protocol-used-in-the-apache2-oidc-proxy>'
+          access_token_type: '<the-access-token-type-used-by-your-idp>'
+          discovery_endpoint: '<the-well-known-endpoint-of-the-idp>'
+        auth_type: 'v3oidcpassword'
+        region_name: '<region>'
+
+The corresponding environment variables would look very similar:
+
+.. code-block:: shell
 
     export OS_PROJECT_NAME=<project-name>
     export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
     export OS_AUTH_URL=<url-to-openstack-identity>
     export OS_IDENTITY_API_VERSION=3
-    export OS_AUTH_PLUGIN=openid
     export OS_AUTH_TYPE=v3oidcpassword
     export OS_USERNAME=<username-in-idp>
     export OS_PASSWORD=<password-in-idp>
@@ -116,7 +169,9 @@ Authentication using username/password i
     export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
     export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
 
-  The corresponding command-line options look very similar::
+Likewise, the corresponding command-line options would look very similar:
+
+.. code-block:: shell
 
     --os-project-name <project-name>
     --os-project-domain-name <project-domain-name>
@@ -134,5 +189,41 @@ Authentication using username/password i
     --os-access-token-type <the-access-token-type-used-by-your-idp>
     --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
 
-If a password is not provided above (in plaintext), you will be interactively
-prompted to provide one securely.
+For more information on configuring authentication, including an overview of
+the many authentication mechanisms supported, refer to the `Authentication
+guide`__. For more information on configuration in general, refer to the
+`Configuration guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
+.. __: https://docs.openstack.org/python-openstackclient/latest/configuration/index.html
+
+Contributing
+============
+
+You can clone the repository from opendev.org::
+
+    git clone https://opendev.org/openstack/python-openstackclient
+    cd python-openstackclient
+
+OpenStack Client uses the same contributor process as other OpenStack projects.
+For information on this process, including help on setting up you Gerrit
+account and an overview of the CI process, refer to the `OpenStack Contributors
+Guide`__.
+
+For more information on contributing to OpenStack Client itself, including
+guidance on how to design new commands and how to report bugs, refer to the
+`Contributors Guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/contributor/index.html
+.. __: https://docs.opendev.org/opendev/infra-manual/latest/developers.html
+
+Links
+-----
+
+* `Issue Tracker <https://bugs.launchpad.net/python-openstackclient>`_
+* `Code Review <https://review.opendev.org/#/q/status:open+project:openstack/openstacksdk,n,z>`_
+* `Documentation <https://docs.openstack.org/python-openstackclient/latest/>`_
+* `PyPi <https://pypi.org/project/python-openstackclient>`_
+* `Mailing list <https://lists.openstack.org/mailman3/lists/openstack-discuss.lists.openstack.org/>`_
+* `Release Notes <https://docs.openstack.org/releasenotes/python-openstackclient>`_
+* `IRC (#openstack-sdks on OFTC (irc.oftc.net)) <irc://irc.oftc.net/openstack-sdks>`_
diff -pruN 7.4.0-3/RELEASENOTES.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/RELEASENOTES.rst
--- 7.4.0-3/RELEASENOTES.rst	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/RELEASENOTES.rst	2025-07-07 22:42:17.000000000 +0000
@@ -0,0 +1,6262 @@
+======================
+python-openstackclient
+======================
+
+.. _python-openstackclient_8.1.0-9:
+
+8.1.0-9
+=======
+
+.. _python-openstackclient_8.1.0-9_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml @ b'572eeb6d38f92669580b34d0d0a2b217fc999179'
+
+- Add ``--property`` option to ``volume list`` command to filter volumes.
+
+
+.. _python-openstackclient_8.1.0:
+
+8.1.0
+=====
+
+.. _python-openstackclient_8.1.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml @ b'34831172598d20e211147a8c3758d2b3383ea256'
+
+- Add filters to search for enabled and disabled users and projects.
+
+.. releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml @ b'5d730f374b63bbc2121a025638b7abe79f156f53'
+
+- Add support for the new ``spice-direct`` console type, as well as the
+  exposing the ability for admins to lookup console connection information
+  via the new ``console connection show`` command.
+
+.. releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml @ b'01c1b1e36fd712cc6d3367ca23525e7e0b3e9f4d'
+
+- The ``--network``, ``--port``, and ``--router`` options of the ``floating
+  ip list`` command can now be specified multiple times.
+
+
+.. _python-openstackclient_8.1.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml @ b'25cd1178b31a3d5582ab4ad77518fb63a856fd88'
+
+- The ``openstack server set`` command has been extended with a new
+  parameter ``--auto-approve`` and the existing ``--state`` parameter
+  has been modified to require confirmation before resetting the state.
+
+.. releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml @ b'ce2a253d5ac8603c61f4e868e2126354e1cfe4db'
+
+- Support for Python 3.9 has been dropped.
+
+.. releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml @ b'4bdd51cbea41e08f4c78bf071ac4f76d18f42b41'
+
+- The following commands have been migrated to SDK:
+  
+  - ``domain create``
+  - ``domain delete``
+  - ``domain list``
+  - ``domain set``
+  - ``domain show``
+
+.. releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml @ b'a2be1b014e020e9effb1a72e45781e47236b9606'
+
+- Migrate ``group`` commands from keystoneclient to SDK.
+
+
+.. _python-openstackclient_8.0.0:
+
+8.0.0
+=====
+
+.. _python-openstackclient_8.0.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml @ b'762a3b10d13716e2bc4cef121d5b70ced6958d42'
+
+- Added four new network agent types to the list method filter:
+  ``ovn-controller``, ``ovn-controller-gateway``, ``ovn-metadata`` and
+  ``ovn-agent``.
+
+.. releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml @ b'07515cd1602841851d72dac30c7b12affee27bbe'
+
+- The router creation command now has the parameter ``--qos-policy``, that
+  allows to set a QoS policy for the provided external gateways (one or
+  many). It is mandatory to define an external gateway if the QoS policy is
+  set.
+
+
+.. _python-openstackclient_8.0.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml @ b'7750fc1cf45a32563225092ec442c96c38ee6769'
+
+- The following commands have been migrated to SDK:
+  
+  - ``endpoint create``
+  - ``endpoint delete``
+  - ``endpoint list``
+  - ``endpoint show``
+  - ``endpoint set``
+
+.. releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml @ b'e6be9a3edf0904762cb6816a04b8d3d146a1f639'
+
+- Support for the Block Storage (Cinder) v1 API has been officially removed
+  as it had been broken for some time. If you haven't noticed then you likely
+  don't need to do anything. However, in the unlikely event that your cloud
+  is using the Block Storage v1 API - or incorrectly advertises the Block
+  Storage v1 API - consider overriding the API version to use v2 as this
+  behaves very similarly. It may also be necessary to set an endpoint
+  override for the Block Storage API if your clouds service catalog is not
+  configured correctly. For example:
+  
+  .. code-block:: yaml
+  
+      example:
+        regions:
+          - name: regionOne
+            values:
+              block_storage_endpoint_override: 'https://blockstorage.api.cloud.example/'
+        volume_api_version: 2
+  
+  If using a public cloud provider, there may also be a profile already
+  published that sets these. These are listed in the `Vendor Support`__
+  doc. For example:
+  
+  .. code-block:: yaml
+  
+      example:
+        profile: rackspace
+  
+  Alternatively, consider use versions of OSC < 3.19 and python-cinderclient
+  < 5.0 (both Stein), since these were the last versions to fully support
+  Cinder v1.
+  
+  .. __: https://docs.openstack.org/openstacksdk/latest/user/config/vendor-support.html
+
+
+.. _python-openstackclient_2.3.1:
+
+2.3.1
+=====
+
+.. _python-openstackclient_2.3.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1560157-bce572f58b43efa1.yaml @ b'53a79c33f88cea83fb2a90408dd3f5e8dd48a2f5'
+
+- Fixed SSL/TLS verification for Network v2 commands. The commands were ignoring the ``--insecure`` and ``--os-cacert`` options and the ``OS_CACERT`` environment variable which caused them to fail with ``An SSL error occurred.`` when authenticating using SSL/TLS. [Bug `1560157 <https://bugs.launchpad.net/python-openstackclient/+bug/1560157>`_]
+
+
+.. _python-openstackclient_2.2.0:
+
+2.2.0
+=====
+
+.. _python-openstackclient_2.2.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml @ b'16f00833a70893979ccdf7ffb7f6e1e7653cdc24'
+
+- OSprofiler support was added. To initiate OpenStack request tracing
+  ``--profile <HMAC_KEY>`` option needs to be added to the CLI command. This
+  key needs to present one of the secret keys defined in the OpenStack
+  projects configuration files (if there is a wish to generate cross-project
+  trace, the chosen key needs to be presented in all these configuration
+  files). By default all OpenStack projects, that support OSprofiler,
+  are using ``SECRET_KEY`` HMAC key.
+  
+  To use tracing functionality OSprofiler (and its storage backend)
+  needs to be installed in the environment. If so, you will be able to
+  trigger profiling via `openstack --profile SECRET_KEY <operation>` command.
+  At the end of output there will be message with <trace_id>, and to plot
+  human-readable HTML chart the following command should be used -
+  ``osprofiler trace show <trace_id> --html --out result.html``.
+
+.. releasenotes/notes/allow-custom-logging-12d55f8ed859ff8e.yaml @ b'cdb7637b76027f74db9b24026a0757084a83195d'
+
+- Allow custom logging of components
+  [Bug `1484660 <https://bugs.launchpad.net/python-openstackclient/+bug/1484660>`_]
+
+.. releasenotes/notes/bug-1519502-f72236598d14d350.yaml @ b'f0960f0fef263298e56d7e81acf50597073becc7'
+
+- Command ``ip floating delete`` is now available for neutron network. [Bug `1519502 <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+
+.. releasenotes/notes/bug-1519502-f72236598d14d350.yaml @ b'f0960f0fef263298e56d7e81acf50597073becc7'
+
+- Command ``ip floating list`` is now available for neutron network. [Bug `1519502 <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+
+.. releasenotes/notes/bug-1519502-f72236598d14d350.yaml @ b'f0960f0fef263298e56d7e81acf50597073becc7'
+
+- Add command ``ip floating show`` for neutron and nova network. [Bug `1519502 <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+
+.. releasenotes/notes/bug-1519512-48624c5a32432a47.yaml @ b'dccde70c57baf9266a795a54198238515d7fdda6'
+
+- Add support for ``security group rule show`` command.
+  [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1538372-ef3a30298357f972.yaml @ b'6b3583ab06459dad8c2aa1b762538516047b8b41'
+
+- Add support for the `server dump create` command
+  [Bug `1538372 <https://bugs.launchpad.net/python-openstackclient/+bug/1538372>`_]
+
+.. releasenotes/notes/bug-1542359-181d28db21a2358a.yaml @ b'112d7b0e0966599aa940de4c0598cea759780785'
+
+- Add ``subnet show`` command.
+  [Bug `1542359 <https://bugs.launchpad.net/bugs/1542359>`_]
+
+.. releasenotes/notes/bug-1542362-ddad607f6d3025f0.yaml @ b'88c92bf71ae026b90b07411772c66b718a7d59e1'
+
+- Add ``subnet delete`` command to openstack-client.
+  [Bug `1542362 <https://bugs.launchpad.net/python-openstackclient/+bug/1542362>`_]
+
+.. releasenotes/notes/bug-1543226-7d885ecaa3715415.yaml @ b'686a26973809eaba3deb9aed63daddba3bb0521e'
+
+- Add ``token revoke`` command for Identity v3
+  [Bug `1543226 <https://bugs.launchpad.net/bugs/1543226>`_]
+
+.. releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml @ b'359dfa1a06683354ace568c78706e3d0a6372c14'
+
+- Command ``network delete`` is now available for nova network. [Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+
+.. releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml @ b'359dfa1a06683354ace568c78706e3d0a6372c14'
+
+- Command ``network list`` is now available for nova network. [Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+
+.. releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml @ b'359dfa1a06683354ace568c78706e3d0a6372c14'
+
+- Command ``network show`` is now available for nova network. [Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+
+.. releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml @ b'359dfa1a06683354ace568c78706e3d0a6372c14'
+
+- Command ``network create`` is now available for nova network. [Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+
+.. releasenotes/notes/bug-1544587-ec3ca453c1340b4e.yaml @ b'79fd6d3f2075ecdfdac8c856be135b3fd1260eb5'
+
+- Add support for ``subnet pool delete`` command. [Bug `1544587 <https://bugs.launchpad.net/python-openstackclient/+bug/1544587>`_]
+
+.. releasenotes/notes/bug-1544589-b9f669ef71aa5e57.yaml @ b'a04012c3d50c3623c699f57d0dd320783b92e1cb'
+
+- Add support for ``subnet pool list`` command. [Bug `1544589 <https://bugs.launchpad.net/python-openstackclient/+bug/1544589>`_]
+
+.. releasenotes/notes/bug-1544590-8cf42954e28c2f42.yaml @ b'3c8bb165137ee1f17d99c270896b37fb9d00f07c'
+
+- Add support for ``subnet pool show`` command. [Bug `1544590 <https://bugs.launchpad.net/python-openstackclient/+bug/1544590>`_]
+
+.. releasenotes/notes/list_role_assignment_names-0db89f50259d4be2.yaml @ b'3a48989eb02187f384cfbf7bb7cd55502741fc68'
+
+- [`bug 1479569 <https://bugs.launchpad.net/python-keystoneclient/+bug/1479569>`_] Add an optional ``--names`` argument to the `role assignment list`` command. This will output names instead of IDs for users, groups, roles, projects, and domains.
+
+.. releasenotes/notes/recursive-container-delete-983361aa9c35ffed.yaml @ b'828f63f903ee71a9f63ebaab3638fe441768a35a'
+
+- Add support for recursive container delete.
+  [Bug `1542718 <https://bugs.launchpad.net/bugs/1542718>`_]
+
+
+.. _python-openstackclient_2.2.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1519511-74bab0e0d32db043.yaml @ b'842882f3cbfca6df9a42bc49b0deefdb84509a8e'
+
+- Ignore the ``security group list`` command ``--all-projects`` option
+  for Network v2 since security groups will be displayed for all projects
+  by default (admin only).
+  [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+
+.. releasenotes/notes/bug-1543214-959aee7830db2b0d.yaml @ b'41e1bd0be64e15a5e0c12b45bdf3dcde5fabf244'
+
+- The ``token issue`` can now return an unscoped token. If a `project` or `domain`
+  target scope are not specified, an unscoped token will be returned.
+  [Bug `1543214 <https://bugs.launchpad.net/bugs/1543214>`_]
+
+.. releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml @ b'ba826fa04fd5f16658da0319f34e26f14d7716d2'
+
+- Command ``flavor set/unset`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+
+.. releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml @ b'ba826fa04fd5f16658da0319f34e26f14d7716d2'
+
+- Command ``security group set`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+
+.. releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml @ b'ba826fa04fd5f16658da0319f34e26f14d7716d2'
+
+- Command ``compute agent set`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+
+.. releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml @ b'ba826fa04fd5f16658da0319f34e26f14d7716d2'
+
+- Command ``aggregate set`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+
+
+.. _python-openstackclient_2.1.0:
+
+2.1.0
+=====
+
+.. _python-openstackclient_2.1.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml @ b'3168e2297d0b48c240b22fb6d8c1b7d05def1e6b'
+
+- Add support for the ``port delete`` command.
+  [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
+
+.. releasenotes/notes/add-port-show-command-de0a599017189a21.yaml @ b'981621e9845934c109c5e4abd9b2ab6828744346'
+
+- Add support for the ``port show`` command.
+  [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
+
+.. releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml @ b'299c5710c518d9502a23f5240360047baa81ac8d'
+
+- Add support for the ``subnet list`` command.
+  [Bug `1523258 <https://bugs.launchpad.net/python-openstackclient/+bug/1523258>`_]
+
+.. releasenotes/notes/bug-1486597-857e20262c038514.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Add ``project unset`` command for Identity v2
+  [Bug `1486597 <https://bugs.launchpad.net/bugs/1486597>`_]
+
+.. releasenotes/notes/bug-1516661-757ef629f899cca3.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Add ``image set --activate|--deactivate`` options (Image v2 only)
+  [Bug `1516661 <https://bugs.launchpad.net/bugs/1516661>`_]
+
+.. releasenotes/notes/bug-1517134-9efecb257910989c.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Add ``--project-domain`` option to ``image create`` and ``image set`` commands
+  (Image v2 only)
+  [Bug `1517134 <https://bugs.launchpad.net/bugs/1517134>`_]
+
+.. releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Add ``router`` commands ``create``, ``delete``, ``list``, ``set``, ``show``
+  [Bug `1519503 <https://bugs.launchpad.net/bugs/1519503>`_]
+
+.. releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Add ``--src-group`` option to ``security group rule create`` to include a
+  'remote' security group rule.
+  [Bug `1522969 <https://bugs.launchpad.net/bugs/1522969>`_]
+
+.. releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml @ b'99f6795189b188b8c560507b7f8101b1cd820392'
+
+- Add volume support to ``os availability zone list``
+  [Bug `1532945 <https://bugs.launchpad.net/bugs/1532945>`_]
+  
+  * New ``--compute`` option to only list compute availability zones.
+  * New ``--volume`` option to only list volume availability zones.
+
+.. releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml @ b'99f6795189b188b8c560507b7f8101b1cd820392'
+
+- Add network support to ``os availability zone list``
+  [Bug `1534202 <https://bugs.launchpad.net/bugs/1534202>`_]
+  
+  * New ``--network`` option to only list network availability zones.
+
+.. releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml @ b'499369329c493f9734248393ff19a82b5e224078'
+
+- Add ``--limit`` option to ``image list`` to limit the number of images
+  in output.
+  [Bug `1540988 <https://bugs.launchpad.net/bugs/1540988>`_]
+
+.. releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml @ b'499369329c493f9734248393ff19a82b5e224078'
+
+- Add ``--marker`` option to ``image list`` to handle paginate requests.
+  [Bug `1540988 <https://bugs.launchpad.net/bugs/1540988>`_]
+
+
+.. _python-openstackclient_2.1.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Make ``security group rule list`` group argument optional to list all
+  security groups
+  [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1520003-505af921c8afffc9.yaml @ b'99f6795189b188b8c560507b7f8101b1cd820392'
+
+- Add remote security group to ``os security group rule list``
+  [Bug `1520003 <https://bugs.launchpad.net/bugs/1520003>`_]
+
+.. releasenotes/notes/bug-1521492-89b972c6362940a5.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Change ``server list --flavor`` to now accept flavor ID or name
+  [Bug `1521492 <https://bugs.launchpad.net/bugs/1521492>`_]
+
+.. releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Change ``server list --image`` to now accept image ID or name
+  [Bug `1521492 <https://bugs.launchpad.net/bugs/1521492>`_]
+
+.. releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Change the ``project set --domain`` option to use the argument as a lookup
+  for locating projects in non-default domains.
+  [Bug `1524456 <https://bugs.launchpad.net/bugs/1524456>`_]
+
+.. releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml @ b'cd4998ef41d7bed8cfb3ae849f522e07162913f5'
+
+- Fix case sensitivity when showing object-store properties.
+  [Bug `1525805 <https://bugs.launchpad.net/bugs/1525805>`_]
+
+.. releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml @ b'5cbecc130ef2aacd5d9bd265b814e6f8140374f9'
+
+- Support non-interactive user password update
+  [Bug `1531360 <https://bugs.launchpad.net/bugs/1531360>`_]
+
+
+.. _python-openstackclient_2.1.0_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml @ b'99f6795189b188b8c560507b7f8101b1cd820392'
+
+- Change the ``--owner`` option to ``--project`` in ``image create`` and ``image set`` commands.  ``--owner`` is deprecated and no longer documented but is still accepted; a warning message will be shown if it is used. [Bug `1527833 <https://bugs.launchpad.net/bugs/1527833>`_]
+
+
+.. _python-openstackclient_2.0.0:
+
+2.0.0
+=====
+
+.. _python-openstackclient_2.0.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/no-project-usage-list-e88eb49aa2e96cf7.yaml @ b'552eded9ad102bfafee734b2a7a4c9aa8d806ce6'
+
+- Removed the deprecated command ``project usage list`` in favor of ``usage list``
+
+
+.. _python-openstackclient_2.0.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1475831-3caafd724d4ed644.yaml @ b'e604a726b2608941dc2b60cf4f071e7777ba2b17'
+
+- Some compute quotas were not being set
+  [Bug `1475831 <https://bugs.launchpad.net/bugs/1475831>`_]
+
+.. releasenotes/notes/bug-1517386-1c0aad8e3203b02b.yaml @ b'e604a726b2608941dc2b60cf4f071e7777ba2b17'
+
+- Add `--all` for `snapshot list`
+  [Bug `1517386 <https://bugs.launchpad.net/bugs/1517386>`_]
+
+.. releasenotes/notes/bug-1519181-932c1ff07ef16666.yaml @ b'552eded9ad102bfafee734b2a7a4c9aa8d806ce6'
+
+- Add Status column to default ``image list`` output (v1 and v2)
+  [Bug `1519181 <https://bugs.launchpad.net/bugs/1519181>`_]
+
+.. releasenotes/notes/bug-1520115-0367e1c8917dc912.yaml @ b'552eded9ad102bfafee734b2a7a4c9aa8d806ce6'
+
+- Fix ``--public|--private`` options for ``volume type create`` command
+  to correctly pass privacy argument to client library
+  [Bug `1520115 <https://bugs.launchpad.net/bugs/1520115>`_]
+
+.. releasenotes/notes/bug-1520541-44d45e4693089c03.yaml @ b'552eded9ad102bfafee734b2a7a4c9aa8d806ce6'
+
+- Fix ``volume delete`` command to delete all specified volumes rather
+  than only the last volume
+  [Bug `1520541 <https://bugs.launchpad.net/bugs/1520541>`_]
+
+
+.. _python-openstackclient_2.0.0_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/add-ksa-7f0795157d93a898.yaml @ b'e604a726b2608941dc2b60cf4f071e7777ba2b17'
+
+- Add dependency on keystoneauth1 module to perform authentication in place
+  of python-keystoneclient.
+
+.. releasenotes/notes/bug-1519510-3cde4643b33ebb7a.yaml @ b'e604a726b2608941dc2b60cf4f071e7777ba2b17'
+
+- Drop Python 2.6 support
+  [Bug `1519510 <https://bugs.launchpad.net/bugs/1519510>`_]
+
+.. releasenotes/notes/server-changes-3962541b6ebdbbd8.yaml @ b'552eded9ad102bfafee734b2a7a4c9aa8d806ce6'
+
+- Changes to ``server`` resource commands:
+  
+  * Added ``--limit`` and ``--marker`` to ``server list``
+  * Added ``server shelve``
+  * Added ``server unshelve``
+  * ``server resume`` now takes multiple server arguments
+  * ``server suspend`` now takes multiple server arguments
+
+
+.. _python-openstackclient_3.2.1-4:
+
+3.2.1-4
+=======
+
+.. _python-openstackclient_3.2.1-4_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml @ b'e79eca55aae02206bd10e663b1540078424d9734'
+
+- Fixed a ``__init__() got an unexpected keyword argument 'project_name'``
+  error in various networking commands when ``help`` or ``--help`` was used.
+  [Bug `1650026 <https://bugs.launchpad.net/bugs/1650026>`_]
+
+
+.. _python-openstackclient_3.2.1:
+
+3.2.1
+=====
+
+.. _python-openstackclient_3.2.1_Security Issues:
+
+Security Issues
+---------------
+
+.. releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml @ b'48e6d8a361ae828c6f3c12f1f3284d7e71cf5338'
+
+- Mask passwords when ``--debug`` or ``-vv`` options are used.
+  [Bug `1630822 <https://bugs.launchpad.net/python-openstackclient/+bug/1630822>`_]
+
+
+.. _python-openstackclient_3.2.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1619274-e78afd7c12ea2c3d.yaml @ b'48e6d8a361ae828c6f3c12f1f3284d7e71cf5338'
+
+- Skip password prompt when running commands that do not require auth and user auth values are present except for password. [Bug `1619274 <https://bugs.launchpad.net/python-openstackclient/+bug/1619274>`_] *Fixed in release 3.3.0*
+
+.. releasenotes/notes/bug-1642301-ad04424c80e8fe50.yaml @ b'48e6d8a361ae828c6f3c12f1f3284d7e71cf5338'
+
+- Fix problem with ``--os-auth-type token_endpoint`` that caused exceptions when recent os-client-config version 1.23.0 or newer is installed. [Bug `1642301 <https://bugs.launchpad.net/bugs/1642301>`_] *Fixed in release 3.4.1*
+
+
+.. _python-openstackclient_3.2.0:
+
+3.2.0
+=====
+
+.. _python-openstackclient_3.2.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1617384-55c88207115e2a5b.yaml @ b'84c83fc3aeebf8201a301f1864c3b8a1572111f1'
+
+- Fix prompting for password issue introduced in release 3.0.0
+  [Bug `1617384 <https://bugs.launchpad.net/bugs/1617384>`_]
+
+
+.. _python-openstackclient_3.0.0:
+
+3.0.0
+=====
+
+.. _python-openstackclient_3.0.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-port-unset-command-8bdaf1fa9c593374.yaml @ b'230d38fb4ca0235706a9cd7617628b84413075b7'
+
+- Add a new command ``port unset`` to clear the information
+  of fixed-ip and binding-profile from the port.
+  [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+.. releasenotes/notes/add-server-group-quotas-b67fcba98619f0c9.yaml @ b'b50c2b6a8847219ec6d3916f429dec77cf2ba180'
+
+- Added support of --server-groups --server-group-members options to ``quota set`` command.
+  [Bug `1602223 <https://bugs.launchpad.net/python-openstackclient/+bug/1602223>`_]
+
+.. releasenotes/notes/bp-backup-snapshot-renamed-for-volume-resource-2d2d13ea8489a61f.yaml @ b'39c5eb9e3fe89bf177e513e447f22b62f5e4785c'
+
+- Add new commands ``volume backup create/delete/list/show/restore``. It is used to replace the old commands ``backup create/delete/list/show/restore``. [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+
+.. releasenotes/notes/bp-implement-network-agents-5eba48796318f094.yaml @ b'722be75f9cffec7242d893cac20d40c570af32d6'
+
+- Add ``network agent delete``, ``network agent list``, ``network agent show`` and ``network agent set`` commands. [Blueprint `implement-network-agents <https://blueprints.launchpad.net/python-openstackclient/+spec/implement-network-agents>`_]
+
+.. releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml @ b'af7ab03693a5708102cf6746563da289e4c1e3b7'
+
+- Support bulk deletion and error handling for ``aggregate delete``, ``flavor delete``, ``keypair delete`` and ``service delete`` commands. [Blueprint `multi-argument-compute <https://blueprints.launchpad.net/python-openstackclient/+spec/multi-argument-compute>`_]
+
+.. releasenotes/notes/bp-multi-argument-network-e43e192ac95db94d.yaml @ b'041ea4978b94149d5037b5afc7743db939b75331'
+
+- Support bulk deletion for ``subnet pool delete``, ``subnet delete``, ``floating ip delete``, ``security group delete`` and ``security group rule delete``. [Blueprint `multi-argument-network <https://blueprints.launchpad.net/python-openstackclient/+spec/multi-argument-network>`_]
+
+.. releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml @ b'412b29b972e4a6877472147f5b713214ace2ca12'
+
+- Update ``--binding-profile`` option on the ``port create`` and ``port set`` commands to support JSON input for more advanced binding profile data. [Blueprint :oscbp:`neutron-client`]
+
+.. releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml @ b'412b29b972e4a6877472147f5b713214ace2ca12'
+
+- Add ``--enable-port-security`` and ``--disable-port-security`` options on the ``network create`` and ``network set`` commands. This supports setting the default port security for ports created on a network. [Blueprint :oscbp:`neutron-client`]
+
+.. releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml @ b'412b29b972e4a6877472147f5b713214ace2ca12'
+
+- Add ``geneve`` choice to the  ``network create`` command ``--provider-network-type`` option. [Blueprint :oscbp:`neutron-client`]
+
+.. releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml @ b'412b29b972e4a6877472147f5b713214ace2ca12'
+
+- Add ``--device-owner`` option to the ``port list`` command to enable listing ports based on device owner. [Blueprint :oscbp:`neutron-client`]
+
+.. releasenotes/notes/bp-neutron-client-rbac-bbd7b545b50d2bdf.yaml @ b'fac321458166cccffc0eb1d13a986a01c9e6d33e'
+
+- Add ``network rbac list``, ``network rbac show``, ``network rbac create``, ``network rbac delete`` and ``network rbac set`` commands. [Blueprint `neutron-client-rbac <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-rbac>`_]
+
+.. releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml @ b'6a6b192ddeb80b516778b1d6e3d34f4261dca85d'
+
+- Add ``--network-segment`` option to the ``subnet create`` command. This is a beta command option and subject to change. Use global option ``--os-beta-command`` to enable this option. [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
+
+.. releasenotes/notes/bug-1575461-3fed33e53795684a.yaml @ b'b0c317ebdd5e5f2626ce2fbd495149336fe5df7e'
+
+- Add support for showing flavor access list by using ``flavor show`` command.
+  [Bug `1575461 <https://bugs.launchpad.net/bugs/1575461>`_]
+
+.. releasenotes/notes/bug-1589332-2941f5286df7e5d4.yaml @ b'954c28dfa21be76b0522af051d71fb9470877a1a'
+
+- Add ``--purge`` option to ``volume delete`` command (Volume v2 only) in
+  order to removing any snapshots along with volume automatically when user
+  delete the volume.
+  [Bug `1589332 <https://bugs.launchpad.net/python-openstackclient/+bug/1589332>`_]
+
+.. releasenotes/notes/bug-1589348-4a612a4efc7ed0e5.yaml @ b'eccd943acc9526311fcfc318280b4be51c42a566'
+
+- Add options ``--up`` and ``--down`` for compute v2 ``compute service set`` command to support force up/down compute service. [Bug `1589348 <https://bugs.launchpad.net/python-openstackclient/+bug/1589348>`_]
+
+.. releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml @ b'6df09fd377f872388d4f855b001a6578ae6fba46'
+
+- Support bulk deletion for ``ec2 credentials delete``, ``endpoint delete``, ``service delete`` in identity V2.0 . [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]
+
+.. releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml @ b'60639d76a742852e18f9e2889c480be95596c268'
+
+- Support bulk deletion for identity v3 commands: ``consumer``,
+  ``credential``, ``domain``, ``ec2creds``, ``endpoint``,
+  ``federation_protocol``, ``identity_provider``, ``mapping``,
+  ``policy``, ``region``, ``service_provider`` and ``service``.
+  [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]
+
+.. releasenotes/notes/bug-1592906-e69b37377278d9c2.yaml @ b'4e62e1e2e18cb93ba0f88bff8727182b1002de4b'
+
+- Support bulk deletion for ``volume type delete``. [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]
+
+.. releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml @ b'fc719f998ce5f826d42f49aecf4f437e6d07857a'
+
+- Add ``--force`` option to ``backup create`` command to allow users to
+  back up an in-use volume.
+  [Bug `1596443 <https://bugs.launchpad.net/bugs/1596443>`_]
+
+.. releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml @ b'dbed97a24df2fb74e4989fb15c912252f8a8bb07'
+
+- Add ``--property`` option to ``flavor create`` command. [Bug `1596798 <https://bugs.launchpad.net/bugs/1596798>`_]
+
+.. releasenotes/notes/bug-1596821-a07599eb4beb6342.yaml @ b'4e46c04f921c81927ded78f17fd28d5a55ebf9e2'
+
+- Add ``--force`` option to ``volume qos delete`` command to allow users to
+  delete in-use QoS specification(s).
+  [Bug `1596821 <https://bugs.launchpad.net/bugs/1596821>`_]
+
+.. releasenotes/notes/bug-1597184-f4fb687b3d4d99d9.yaml @ b'6364df4cbd33a20ea1c729e0031b1aebd3fcd6df'
+
+- Add ``--snapshot`` option to ``backup create`` command.
+  [Bug `1597184 <https://bugs.launchpad.net/bugs/1597184>`_]
+
+.. releasenotes/notes/bug-1597188-a2ff62b809865365.yaml @ b'f5aef9ac36257cfd9808c0dbdb80c5adc412876b'
+
+- Add ``--force`` option to ``backup delete`` command to allow delete
+  in state other than error or available.
+  [Bug `1597188 <https://bugs.launchpad.net/bugs/1597188>`_]
+
+.. releasenotes/notes/bug-1597192-52801f7520287309.yaml @ b'3222ffc157b6e686249fb2e3d4375c89384bfb97'
+
+- Add ``--property`` option to ``snapshot create`` command. [Bug `1597192 <https://bugs.launchpad.net/bugs/1597192>`_]
+
+.. releasenotes/notes/bug-1597198-e36b55f3fd185a3a.yaml @ b'e31408d2a4c524181c37ef565b021c0b729cbbe3'
+
+- Add ``--public`` and ``--private`` options to ``volume type list`` command.
+  [Bug `1597198 <https://bugs.launchpad.net/bugs/1597198>`_]
+
+.. releasenotes/notes/bug-1600196-6a733dd4e3371df7.yaml @ b'34812655a5b44623a04fc05f1a6c9110f4afbc25'
+
+- Add ``--incremental`` option to ``backup create`` command to allow users to
+  create incremental backups.
+  [Bug `1600196 <https://bugs.launchpad.net/python-openstackclient/+bug/1600196>`_]
+
+.. releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml @ b'e310682235810759c17278365fcb76fac438f582'
+
+- Add ``--project`` and ``--project-domain`` options to ``volume type create`` command. [Bug `1602169 <https://bugs.launchpad.net/bugs/1602169>`_]
+
+.. releasenotes/notes/bug-1605088-fea9347336764469.yaml @ b'cf20225347766240a2ebb155e6e46b85f84a3ddc'
+
+- Support to get server ``rdp``, ``serial``, ``mks`` type console url. [Bug `1605088 <https://bugs.launchpad.net/python-openstackclient/+bug/1605088>`_]
+
+.. releasenotes/notes/bug-1605475-84e649fb8c675737.yaml @ b'61b9d9fe2d0c6c99d5e77361111f02a19d169782'
+
+- Add ``--limit`` and ``--marker`` options to ``snapshot list`` command.
+  [Bug `1605475 <https://bugs.launchpad.net/bugs/1605475>`_]
+
+.. releasenotes/notes/bug-1605774-28aec51f6ec4926e.yaml @ b'713d92df4e53f74698a1ff2dfcb7514ff22f023b'
+
+- Deprecate ``role list`` arguments in favor of ``role assignment`` command. [Bug `1605774 <https://bugs.launchpad.net/python-openstackclient/+bug/1605774>`_]
+
+.. releasenotes/notes/bug-1606105-ca06b230e22ab5c6.yaml @ b'5eb7e626b18b033f97f3cf10f2791529f9d75789'
+
+- Add support for domain specific roles in ``role`` and``role assignment`` commands. [Bug `1606105 <https://bugs.launchpad.net/python-openstackclient/+bug/1606105>`_]
+
+.. releasenotes/notes/bug-1610883-e6345c32a35cc290.yaml @ b'831546fb9e4150074baecee9470a0b8d681e0f86'
+
+- Make ``subnet list`` command supports listing up subnets with
+  dhcp enabled/disabled by adding ``--dhcp`` and ``--no-dhcp``
+  options to the command.
+  [Bug `1610883 <https://bugs.launchpad.net/bugs/1610883>`_]
+
+.. releasenotes/notes/bug_1602073-5deb58deeafbc8be.yaml @ b'8bbf30498eb34990cb9bc7c7af418216d47f0421'
+
+- Add "Checksum" column to output of "image list --long" [Bug `1602073 <https://bugs.launchpad.net/bugs/1602073>`_]
+
+.. releasenotes/notes/flavor-create-with-project-19d41bfa93e3c6d0.yaml @ b'014835930d50130a2efca0786920876efc60a8eb'
+
+- Add ``--project`` and ``--project-domain`` options to the ``flavor create`` command. We can use these options to add the flavor access to a given project when we create the flavor.
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Add new command ``floating ip pool list`` to list up all floating ip pools. This command is used to replace the old command ``ip floating pool list``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Add new commands ``server add/remove floating ip``. They are used to replace the old commands ``ip floating add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Add new commands ``server add/remove fixed ip``. They are used to replace the old commands ``ip fixed add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Add new commands ``floating ip create/delete/list/show``. It is used to replace the old commands ``ip floating create/delete/list/show``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/list_volume_type_access-f7d9aa6159f757ea.yaml @ b'5e8957ef7f4acea1ece06378c050021b64ea3f6f'
+
+- Show project access details for private volume type.
+  
+  An user can list projects which have access to
+  a specific private volume type by using
+  ``volume type show <volume-type>``
+  
+  [Bug `1554891 <https://bugs.launchpad.net/python-openstackclient/+bug/1554891>`_]
+
+.. releasenotes/notes/subnet-unset-5b458cdbaf93d766.yaml @ b'45b026d7c8e4675a598192bcf4c88f22005cc1d2'
+
+- Add a new command ``subnet unset`` to clear the information
+  of allocation-pools, host-routes or DNS servers from the subnet.
+  [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+.. releasenotes/notes/unset-router-7b0cbd9518bb1de6.yaml @ b'ed64788cf1a247ca03174770d43d8c7816cc0ad1'
+
+- Add a new command ``router unset`` to clear the information
+  of routes from the router.
+  [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+.. releasenotes/notes/unset-subnet-pool-333052dd85b95653.yaml @ b'063c722a110031883e9615064092644de6df8da2'
+
+- Add a new command ``subnet pool unset`` to clear the information
+  of pool-prefixes from the subnet pools.
+  [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+
+.. _python-openstackclient_3.0.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/bug-1588588-39927ef06ca35730.yaml @ b'9c62af8a42ebfeb60d88f5ad0af7c1c2fd562853'
+
+- All ``set`` and ``unset`` commands now return normally when nothing specified to modify. This will become the default behavior of OSC ``set`` and ``unset`` commands. [Bug `1588588 <https://bugs.launchpad.net/python-openstackclient/+bug/1588588>`_]
+
+.. releasenotes/notes/modify-compute-agent-set-77ff894ef62ebbc7.yaml @ b'25bdf6811c71413921777cad73b6d039444600ff'
+
+- Migrate command ``compute agent set`` arguments to be optional.
+
+.. releasenotes/notes/remove-osc_password-0767ac78267ef114.yaml @ b'ccbb2dd1e8aaa5d2f34a30763f71125688c8dfac'
+
+- With the change to use keystoneauth plugins the OpenStackClient-specific ``osc_password`` authentication plugin has been removed.  The visible difference should only be in the behaviour with poorly configured clouds with old default Keystone values for admin_endpoint and public_endpoint as seen in the version details returned in a GET to the root ('/') route.
+
+
+.. _python-openstackclient_3.0.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/bp-backup-snapshot-renamed-for-volume-resource-2d2d13ea8489a61f.yaml @ b'39c5eb9e3fe89bf177e513e447f22b62f5e4785c'
+
+- Deprecate commands ``backup create/delete/list/show/restore``. [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Deprecate command ``ip floating pool list``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Deprecate commands ``ip floating add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Deprecate commands ``ip fixed add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+.. releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml @ b'0aa2304f38da0696576827fc4d71f2cf7cc13ad6'
+
+- Deprecate commands ``ip floating create/delete/list/show``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+
+
+.. _python-openstackclient_3.0.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1535213-c91133586e07d71c.yaml @ b'20ae54045cef136a8d0665aab0d45698e12ed21c'
+
+- Support a new ``--state`` option for ``volume set`` command that
+  changes the state of a volume.
+  [Bug `1535213 <https://bugs.launchpad.net/bugs/1535213>`_]
+
+.. releasenotes/notes/bug-1543222-6f8579344ff5c958.yaml @ b'2740291f491804be5f521770ee773fa62894e8a3'
+
+- Keystone V3 `user password set` is a self-service operation. It should not required a scoped token as it is not considered a `scoped operation`. [Bug `1543222 <https://bugs.launchpad.net/bugs/1543222>`_]
+
+.. releasenotes/notes/bug-1561599-d5f541f08ae6274a.yaml @ b'337d013c94378a4b3f0e8f90e4f5bd745448658f'
+
+- When performing ``domain show``, ``project show`` or ``user show``, peek into the user token to determine the ID or the resource (if supplied with only a name). This should make finding information about the user and their project easier for non-admin users. [Bug `1561599 <https://bugs.launchpad.net/bugs/1561599>`_]
+
+.. releasenotes/notes/bug-1582774-3bba709ef61e33b7.yaml @ b'099a2c38b99dff6a0909c0a3ba2909f1aea58644'
+
+- Fix setting defaults for some scope parameters, that were putting invalid scope parameters for some auth plugins. [Bug `1582774 <https://bugs.launchpad.net/bugs/1582774>`_]
+
+.. releasenotes/notes/bug-1589935-8a56e6a18d836db9.yaml @ b'cf122397733b8795530577b7824aeae305719658'
+
+- Raise ``ArgumentTypeError`` if the input arguments do not match the type ``key=value`` when we set properties. [Bug `1589935 <https://bugs.launchpad.net/bugs/1589935>`_]
+
+.. releasenotes/notes/bug-1592062-e327a31a5ae66809.yaml @ b'fe0c8e955be0331aef9cc6847c9bddc43ce66d92'
+
+- Scope options are now validated after authentication occurs, and only if the user does not have a default project scope. [Bug `1592062 <https://bugs.launchpad.net/bugs/1592062>`_]
+
+.. releasenotes/notes/bug-1592368-a4af69f163a1e208.yaml @ b'b875f63a6f2a7ac381d4bb80b9c032272126ef49'
+
+- Fix for network OS_ENDPOINT_TYPE/--os-interface. Previously these were being ignored for network commands which resulted in the public endpoint always being used. [Bug `1592368 <https://bugs.launchpad.net/bugs/1592368>`_]
+
+.. releasenotes/notes/bug-1592761-f45998453d6801f7.yaml @ b'ca5e8e6c8540e457a620cc90d321a08e7417de32'
+
+- Add default IP version in ``ip availability list`` command and make this command work properly without ``--ip-version`` option. [Bug `1592761 <https://bugs.launchpad.net/bugs/1592761>`_]
+
+.. releasenotes/notes/bug-1597296-9735f33eacf5552e.yaml @ b'c45b1d7b230e900d0416a4953607e5d4e1dc9cfd'
+
+- Fixed service name lookup in Identity commands to properly handle multiple matches. [Bug `1597296 <https://bugs.launchpad.net/python-openstackclient/+bug/1597296>`_]
+
+
+.. _python-openstackclient_2.6.0:
+
+2.6.0
+=====
+
+.. _python-openstackclient_2.6.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-server-backup-e63feaebb6140f83.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``server backup create`` command
+
+.. releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``network segment list`` and ``network segment show`` commands. These are beta commands and subject to change. Use global option ``--os-beta-command`` to enable these commands. [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
+
+.. releasenotes/notes/bug-1554886-8e5249a655e7e7b6.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``volume transfer request list`` command
+  [:lpbug:`1554886`]
+
+.. releasenotes/notes/bug-1575461-4d7d90e792132064.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``--project`` option to ``flavor set`` command to set project access
+  to a flavor
+  [:lpbug:`1575461`]
+
+.. releasenotes/notes/bug-1575461-4d7d90e792132064.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``--project`` option to ``flavor unset`` command to remove project access
+  to a flavor
+  [:lpbug:`1575461`]
+
+.. releasenotes/notes/bug-1582968-4d44912a033b242c.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``image unset`` command [:lpbug:`1582968`]
+
+.. releasenotes/notes/ip-availability-ca1cf440f6c70afc.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- Add ``ip availability list`` and  ``ip availability show`` commands
+  [Blueprint :oscbp:`neutron-ip-capacity`]
+
+.. releasenotes/notes/server-set-state-214b12ec2161de4d.yaml @ b'1a7284f63ad13f41c6ff4295d69f065310242524'
+
+- Add ``--state`` option to ``server set`` command to set the server to
+  active or error state.
+  [Blueprint `server-reset-state <https://blueprints.launchpad.net/python-openstackclient/+spec/server-reset-state>`_]
+
+
+.. _python-openstackclient_2.6.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/address-scope-delete-multi-31c3af73feb31265.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- ``address scope delete`` command now accepts multiple address scopes
+  in a single command
+
+.. releasenotes/notes/compute-agent-deff48988e81b30e.yaml @ b'd24c255e4302c37b3a4fa4051b263b3d5e0b9b92'
+
+- ``compute agent delete`` command now supports deleting multiple agents
+  in a single command
+
+.. releasenotes/notes/service-set-option-61772a8940ad0778.yaml @ b'ac1d86c34333780e30b9393d155ae84a769ac222'
+
+- An exception is not raised by command ``service set`` when nothing specified. Instead, the service is not enabled by default. And if ``--disable-resion`` is specified but not ``--disable``, an exception will be raised.
+
+
+.. _python-openstackclient_2.6.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1588384-eb6976fcfb90cb4c.yaml @ b'6f2c1734e3d66e261f231711455821321c1fc254'
+
+- Fix the ``--enable`` option on all commands by changing the ``--enable-beta-commands`` global option to ``--os-beta-command``. There are no upgrade impacts for the global option rename since the old name isn't used. [Bug `1588384 <https://bugs.launchpad.net/python-openstackclient/+bug/1588384>`_]
+
+
+.. _python-openstackclient_2.5.0:
+
+2.5.0
+=====
+
+.. _python-openstackclient_2.5.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-quota-set-for-network-11fcd7b9e08624b5.yaml @ b'b92cf77fb58b4aafcf4b3a1ef6b89fd15166505b'
+
+- Add network support for ``quota set`` command. Options added includes
+  ``--networks --subnets --subnetpools --ports --routers --rbac-policies``
+  ``--vips --members --health-monitors``.
+  Options ``--floating-ips --secgroup-rules --secgroups`` now support
+  both network and compute API.
+  [Bug `1489441 <https://bugs.launchpad.net/bugs/1489441>`_]
+
+.. releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml @ b'fd5fd924d152338204fcf69673fedd31a3904977'
+
+- Add ``--icmp-type`` and ``--icmp-code`` options to the ``security group rule create`` command for Network v2 only. These options can be used to set ICMP type and code for ICMP IP protocols. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml @ b'fd5fd924d152338204fcf69673fedd31a3904977'
+
+- The following Network v2 IP protocols are supported by the ``security group rule create`` command ``--protocol`` option, ``ah``, ``dccp``, ``egp``, ``esp``, ``gre``, ``igmp``, ``ipv6-encap``, ``ipv6-frag``, ``ipv6-icmp``, ``ipv6-nonxt``, ``ipv6-opts``, ``ipv6-route``, ``ospf``, ``pgm``, ``rsvp``, ``sctp``, ``udplite``, ``vrrp`` and integer representations [0-255]. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml @ b'fd5fd924d152338204fcf69673fedd31a3904977'
+
+- The ``security group rule list`` command supports displaying the ICMP type and code for security group rules with the ICMP IP protocols. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1542171-fde165df53216726.yaml @ b'99031cf1ed36b3c3b8c09e2c64aaa4b789eb25b9'
+
+- Add ``server group create``, ``server group delete``,
+  ``server group list``, ``server group show`` commands.
+  [Bug `1542171 <https://bugs.launchpad.net/python-openstackclient/+bug/1542171>`_]
+  [Blueprint `nova-server-group-support <https://blueprints.launchpad.net/python-openstackclient/+spec/nova-server-group-support>`_]
+
+.. releasenotes/notes/bug-1544586-0fe19a567d3e31fc.yaml @ b'48ebc49f201baea443146a8d1c3b6cbde3b2f297'
+
+- Add ``--share`` and ``--default`` options to ``subnet pool create`` and ``--default`` option to ``subnet pool set`` [Bug `1544586 <https://bugs.launchpad.net/python-openstackclient/+bug/1544586>`_] [Bug `1544591 <https://bugs.launchpad.net/python-openstackclient/+bug/1544591>`_]
+
+.. releasenotes/notes/bug-1545537-4fa72fbfbbe3f31e.yaml @ b'99031cf1ed36b3c3b8c09e2c64aaa4b789eb25b9'
+
+- Add ``--transparent-vlan`` and ``--no-transparent-vlan`` options to
+  ``network create`` and ``network set`` commands to add/remove VLAN
+  transparency attributes from networks.
+  This option is available in Network V2 only.
+  [Bug `1545537 <https://bugs.launchpad.net/bugs/1545537>`_]
+
+.. releasenotes/notes/bug-1550999-5e352a71dfbc828d.yaml @ b'99031cf1ed36b3c3b8c09e2c64aaa4b789eb25b9'
+
+- Adds ``volume service list`` command.
+  [Bug `1550999 <https://bugs.launchpad.net/python-openstackclient/+bug/1550999>`_]
+
+.. releasenotes/notes/bug-1561838-3a006a8263d7536d.yaml @ b'a5a343a5a86658246cc136a330eee951e32c7b56'
+
+- Support X.latest format for OS_COMPUTE_API_VERSION in order to talk with the latest nova microversion API, that is very helpful shortcut usage to use new nova side features. [Bug `1561838 <https://bugs.launchpad.net/python-openstackclient/+bug/1561838>`_]
+
+.. releasenotes/notes/bug-1566269-2572bca9157ca107.yaml @ b'99031cf1ed36b3c3b8c09e2c64aaa4b789eb25b9'
+
+- Add ``address scope create``, ``address scope delete``, ``address scope list``, ``address scope set`` and ``address scope show`` commands. [Bug `1566269 <https://bugs.launchpad.net/python-openstackclient/+bug/1566269>`_]
+
+.. releasenotes/notes/bug-1581179-4d15dc504777f9e7.yaml @ b'668bc028d13b80dfc6ecbef6193678a97e64fdc1'
+
+- Add the ``--ip-version`` option to the ``subnet list`` command. This will output subnets based on IP version filter. [`Bug 1581179 <https://bugs.launchpad.net/python-openstackclient/+bug/1581179>`_]
+
+
+.. _python-openstackclient_2.5.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml @ b'fd5fd924d152338204fcf69673fedd31a3904977'
+
+- Changed the ``security group rule create`` command ``--proto`` option to ``--protocol``. Using the ``--proto`` option is still supported, but is no longer documented and may be deprecated in a future release. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+
+.. _python-openstackclient_2.5.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1535239-767e6cf1990eda01.yaml @ b'189e4774f88243669ee1b9089d6c39021094c83d'
+
+- Support a new ``--state`` option for ``snapshot set`` command that
+  changes the state of a snapshot.
+  [Bug `1535239 <https://bugs.launchpad.net/bugs/1535239>`_]
+
+.. releasenotes/notes/bug-1536479-d1f03ed2177d06ed.yaml @ b'08759b853a2611144a2d3f0e9216d6801fc23ef2'
+
+- ``--pool-prefix`` option made required for ``subnet pool create``
+  [Bug `1536479 <https://bugs.launchpad.net/bugs/1536479>`_]
+
+.. releasenotes/notes/bug-1556719-d2dcf61acf87e856.yaml @ b'56f9227063cb86594600ccc80c661101f0f0c2c8'
+
+- Command ``network delete`` will delete as many networks as possible, log and report failures in the end. [Bug `1556719 <https://bugs.launchpad.net/python-openstackclient/+bug/1556719>`_] [Bug `1537856 <https://bugs.launchpad.net/python-openstackclient/+bug/1537856>`_]
+
+.. releasenotes/notes/bug-1564460-ab7ad35c02392cb4.yaml @ b'a90c824e0407f931b5c45df53103b43aa564de12'
+
+- Fixed the ``--route`` option on the ``router set`` command which did not properly format the new routes to set resulting in a ``Bad Request`` error. In addition, the ``router create``, ``router list`` and ``router show`` command output for routes was fixed to improve readability and to align with the ``--route`` option on the ``router set`` command. [Bug `1564460 <https://bugs.launchpad.net/bugs/1564460>`_]
+
+.. releasenotes/notes/bug-1565034-dd404bfb42d7778d.yaml @ b'bc93ebfe5c0fa4d29b79fa3fd93ec603425997ea'
+
+- Added ``--no-route`` to the ``router set`` command. Deprecated ``--clear-routes``. [Bug `1565034 <https://bugs.launchpad.net/bugs/1565034>`_]
+
+.. releasenotes/notes/bug-1572228-03638a7adec5da8b.yaml @ b'9f3fa5ee3bf87c47f7a38ef78f4022ac46b2f2f6'
+
+- Fixed ``network create``, ``network show`` and ``network list`` commands to correctly display the router type in the ``router:external`` and ``Router Type`` columns. [Bug `1572228 <https://bugs.launchpad.net/bugs/1572228>`_]
+
+.. releasenotes/notes/bug-1572733-874b37a7fa8292d0.yaml @ b'27024d70af4756cb6e4b210b025ed7427541f773'
+
+- The ``quota show`` command ``<project/class>`` argument is now optional. If not specified, the user's current project is used. This allows non-admin users to show quotas for their current project. [Bug `1572733 <https://bugs.launchpad.net/bugs/1572733>`_]
+
+.. releasenotes/notes/bug-1575478-5a0a923c3a32f96a.yaml @ b'681d6dc2de83ef13b4fb2fb4abe70f3c1ccb0e10'
+
+- Fixed ``flavor show/delete/set/unset`` command to properly find a private flavor by flavor name. [Bug `1575478 <https://bugs.launchpad.net/bugs/1575478>`_]
+
+.. releasenotes/notes/bug-1575624-87957ff60ad661a6.yaml @ b'4524b3605fa4260a2f916421eebfc7a99b320e4b'
+
+- Fixed ``flavor set/unset`` command to properly find a flavor to be set/unset by flavor id. [Bug `1575624 <https://bugs.launchpad.net/bugs/1575624>`_]
+
+
+.. _python-openstackclient_2.4.0:
+
+2.4.0
+=====
+
+.. _python-openstackclient_2.4.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-disable-reason-6e0f28459a09a60d.yaml @ b'ad6727df8800a61a5890995a1e572e6f5b9bab01'
+
+- Add ``--disable-reason`` option to the ``service set`` command
+
+.. releasenotes/notes/add-port-commands-a3580662721a6312.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- Add ``port create``, ``port list`` and ``port set`` commands
+  [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
+
+.. releasenotes/notes/add-restore-server-d8c73e0e83df17dd.yaml @ b'ad6727df8800a61a5890995a1e572e6f5b9bab01'
+
+- Add ``server restore`` command
+
+.. releasenotes/notes/bug-1519511-65b8901ae6ea2e63.yaml @ b'ad6727df8800a61a5890995a1e572e6f5b9bab01'
+
+- The ``security group create``, ``security group set`` and ``security group show`` commands now uses Network v2 when enabled which results in a more detailed output for network security group rules. [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+
+.. releasenotes/notes/bug-1519511-65d8d21dde31e5e2.yaml @ b'a7c76878da02da406c9ccbcd62cc40def1108faa'
+
+- Add ``--project`` and ``--project-domain`` options to the ``security group create`` command for Network v2. [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+
+.. releasenotes/notes/bug-1519512-48d98f09e44220a3.yaml @ b'a5a9caea2b06a69953f692289866e59f52d78a4c'
+
+- Add ``--ingress``, ``--egress``, ``--ethertype``, ``--project`` and ``--project-domain`` options to the ``security group rule create`` command for Network v2 only. These options enable ``egress`` and ``IPv6`` security group rules along with setting the project. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1519512-65df002102b7fb99.yaml @ b'94c9cd5c66512d52b31dfaa42bc3d1cc7fd81702'
+
+- The ``security group rule list`` command now uses Network v2 when enabled which results in ``egress`` security group rules being displayed. The ``--long`` option was also added for Network v2 to display direction and ethertype information. In addition, security group rules for all projects will be displayed when the ``group`` argument is not specified (admin only). This is done by default when using Network v2, but requires the new ``--all-projects`` option when using Compute v2. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1540656-f7b7b7e3feef2440.yaml @ b'2109bce85a40da3e3cbebed1cac661611564ccb2'
+
+- The ``security group rule create`` command now supports a security group name for the ``--src-group`` option. [Bug `1540656 <https://bugs.launchpad.net/bugs/1540656>`_]
+
+.. releasenotes/notes/bug-1542364-5d1e93cfd24f0b65.yaml @ b'71b8919054fc7cc7f95006f6d7e2bcee18c955e5'
+
+- Add ``subnet create`` command.
+  [Bug `1542364 <https://bugs.launchpad.net/bugs/1542364>`_]
+
+.. releasenotes/notes/bug-1544586-0e6ca9a09dac0726.yaml @ b'ad6727df8800a61a5890995a1e572e6f5b9bab01'
+
+- Add ``subnet pool create`` and ``subnet pool set`` commands. [Bug `1544586 <https://bugs.launchpad.net/python-openstackclient/+bug/1544586>`_] [Bug `1544591 <https://bugs.launchpad.net/python-openstackclient/+bug/1544591>`_]
+
+.. releasenotes/notes/bug-1545537-12bbf01d2280dd2f.yaml @ b'aa1495e241e99903bc8704f1981a7e3941803e35'
+
+- Add provider network options ``--provider-network-type``,
+  ``--provider-physical-network`` and ``--provider-segment``
+  to the ``network create`` and ``network set`` commands.
+  These options are available for NetworkV2 only.
+  [Bug `1545537 <https://bugs.launchpad.net/bugs/1545537>`_]
+
+.. releasenotes/notes/bug-1545537-7a66219d263bb1e5.yaml @ b'67f8b898eb6d48b11b9f0624ac70f65c4311f8e8'
+
+- Add external network options ``--external|--internal`` and ``--external``
+  suboptions ``--default|--no-default`` to the ``network create`` and
+  ``network set`` commands.
+  These options are available for Network version 2 only.
+  [Bug `1545537 <https://bugs.launchpad.net/bugs/1545537>`_]
+
+.. releasenotes/notes/bug-1554877-7f8479791eab45b7.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- Add ``--image-property`` option to ``volume set`` and ``volume unset`` commands
+  
+  Image properties are copied when a volume is created from an image.
+  The properties are immutable on the image itself but may be updated
+  or removed from the volume created from that image.
+  
+  [Bug `1554877 <https://bugs.launchpad.net/python-openstackclient/+bug/1554877>`_]
+  [Bug `1554879 <https://bugs.launchpad.net/python-openstackclient/+bug/1554879>`_]
+
+.. releasenotes/notes/bug-1554889-32ba8d4bfb0f5f3d.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- Add ``--project`` and ``--project-domain`` options to ``volume type set``
+  and ``volume type unset`` commands
+  
+  Use the ``--project`` option to restrict a volume type to a specific project.
+  Volume types are public by default, restricted volume types should be made
+  private with the ``--private`` option to the ``volume create`` command.
+  
+  [Bug `1554889 <https://bugs.launchpad.net/python-openstackclient/+bug/1554889>`_]
+  [Bug `1554890 <https://bugs.launchpad.net/python-openstackclient/+bug/1554890>`_]
+
+.. releasenotes/notes/bug-1556929-edd78cded88ecdc9.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- Add ``host set`` command [Bug `1556929 <https://bugs.launchpad.net/python-openstackclient/+bug/1556929>`_]
+
+.. releasenotes/notes/bug-1559866-733988f5dd5b07bb.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- Add ``aggregate unset`` command [Bug `1559866 <https://bugs.launchpad.net/python-openstackclient/+bug/1559866>`_]
+
+.. releasenotes/notes/bug-1565112-e0cea9bfbcab954f.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- Add global options ``os-cert`` and ``--os-key`` to support client certificate/key.  Environment variables ``OS_CERT`` and ``OS_KEY``, as well as the ``cert`` and ``key`` values in clouds.yaml may also be used [Bug `1565112 <https://bugs.launchpad.net/bugs/1565112>`_]
+
+.. releasenotes/notes/router-port-add-0afe7392c080bcb8.yaml @ b'2e94f2803fca3862589fe2b10c76c2ebc9e17229'
+
+- Add ``router add port`` command
+  [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+.. releasenotes/notes/router-remove-port-058078c93819b0f4.yaml @ b'8ecdc57ea680b7e20835bea69a2d18e1460d9406'
+
+- Add ``router remove port`` command
+  [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+.. releasenotes/notes/router-subnet-469d095ae0bac884.yaml @ b'9e42daa577b0f15c349c2f4a79b3632ffec97720'
+
+- Add ``router add subnet`` command
+  [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+.. releasenotes/notes/router-subnet-469d095ae0bac884.yaml @ b'9e42daa577b0f15c349c2f4a79b3632ffec97720'
+
+- Add ``router remove subnet`` command
+  [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+.. releasenotes/notes/subnet-set-bbc26ecc16929302.yaml @ b'2b95e363d325c686db229a9da1d9a3a7677e8294'
+
+- Add ``subnet set`` command.
+  [Bug `1542363 <https://bugs.launchpad.net/bugs/1542363>`_]
+
+
+.. _python-openstackclient_2.4.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/bug-1519502-d534db6c18adef20.yaml @ b'baf96411fed22ad97ff219601830be63563ae03a'
+
+- The ``ip floating create`` command now uses Network v2 when enabled [Bug `1519502 <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+
+.. releasenotes/notes/bug-1519512-4231ac6014109142.yaml @ b'd90650796217fbb9cdd19297ee6ff59f0e009413'
+
+- The ``security group rule create`` command now uses Network v2 when enabled which results in a more detailed output for network security group rules that matches the ``security group rule show`` command. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1571812-49cdce4df5f3d481.yaml @ b'530fe42589a2138278f100f791d8c6d3fbed8950'
+
+- Deprecate global option ``--profile`` in favor of ``--os-profile``.
+  
+  ``--profile`` interferes with existing command options with the same name.
+  Unfortunately it appeared in a release so we must follow the deprecation
+  process and wait one year (April 2017) before removing it.
+  
+  [Bug `1571812 <https://bugs.launchpad.net/python-openstackclient/+bug/1571812>`_]
+
+
+.. _python-openstackclient_2.4.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1519511-65b8901ae6ea2e63.yaml @ b'ad6727df8800a61a5890995a1e572e6f5b9bab01'
+
+- The ``security group create`` command now uses Network v2 when enabled which allows the security group description to be created with an empty value. In addition, the ``tenant_id`` field changed to ``project_id`` to match the ``security group show`` command output. [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+
+.. releasenotes/notes/bug-1519512-65df002102b7fb99.yaml @ b'94c9cd5c66512d52b31dfaa42bc3d1cc7fd81702'
+
+- The ``security group rule list`` command no longer ignores the ``group`` argument when it is set to an empty value. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+.. releasenotes/notes/bug-1545609-bdc1efc17214463b.yaml @ b'f0c3b4e69dc56934305442b505d5f5f68579f1f2'
+
+- Fixed ``openstack command list`` to display properly
+  [Bug `1545609 <https://bugs.launchpad.net/python-openstackclient/+bug/1545609>`_]
+
+.. releasenotes/notes/bug-1560157-bce572f58b43efa1.yaml @ b'b5f10f43eb9fd1a046a3e80db09d8bc8c350c218'
+
+- Fixed SSL/TLS verification for Network v2 commands. The commands were ignoring the ``--insecure`` and ``--os-cacert`` options and the ``OS_CACERT`` environment variable which caused them to fail with ``An SSL error occurred.`` when authenticating using SSL/TLS. [Bug `1560157 <https://bugs.launchpad.net/python-openstackclient/+bug/1560157>`_]
+
+.. releasenotes/notes/bug-1569480-c52e330548bfbd78.yaml @ b'3a4d53a93bb62f5bd2e21db1727ef74f771075d8'
+
+- Fixed ``subnet pool list`` command to properly disply the list of subnet pool prefixes in the ``Prefixes`` column. This fix is consistent with the ``subnet pool create`` and ``subnet pool show`` command output. [Bug `1569480 <https://bugs.launchpad.net/bugs/1569480>`_]
+
+.. releasenotes/notes/make-snapshot-and-backup-name-optional-01971d33640ef1c8.yaml @ b'311e775c81419c3b28d03e616a0e415a614b9cff'
+
+- Make ``--name`` optional in ``volume snapshot create`` and ``volume backup create`` commands.
+
+
+.. _python-openstackclient_3.8.2:
+
+3.8.2
+=====
+
+.. _python-openstackclient_3.8.2_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1659967-644a8ee3621c9e81.yaml @ b'253a92ec8f2b7bd5d8f056210dea374f2e2ae184'
+
+- ``security group list`` command now can display project IDs in the ``Project`` column
+  of the command output.
+  [Bug `1659967 <https://bugs.launchpad.net/bugs/1659967>`_]
+
+.. releasenotes/notes/bug-1711301-17754f487973d4c1.yaml @ b'f2120f15d54ba8b23748663c81650e3fd7a6efd1'
+
+- Fix occurrences of the ``network agent delete`` command failing with newer
+  releases of python-openstacksdk.
+  [Bug `1711301 <https://bugs.launchpad.net/python-openstackclient/+bug/1711301>`_]
+
+
+.. _python-openstackclient_3.8.1:
+
+3.8.1
+=====
+
+.. _python-openstackclient_3.8.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1659878-f6a55b7166d99ca8.yaml @ b'1e3dc48c64304eb378660ceb531aab3d42ac0710'
+
+- The ``network create`` command was ignoring the ``--project`` option and
+  creating networks owned by the current authenticated user's project.  This
+  was a regression introduced in OSC 3.8.0.
+  [Bug `1659878 <https://bugs.launchpad.net/bugs/1659878>`_]
+
+.. releasenotes/notes/bug-1659993-a5fe43bef587e490.yaml @ b'1e3dc48c64304eb378660ceb531aab3d42ac0710'
+
+- The ``address scope list`` command failed with 'HttpException: Bad Request'
+  when the ``--share`` or ``--no-share`` options were used.
+  [Bug `1659993 <https://bugs.launchpad.net/bugs/1659993>`_]
+
+
+.. _python-openstackclient_3.8.0:
+
+3.8.0
+=====
+
+.. _python-openstackclient_3.8.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/bp-neutron-client-metering-6f8f9527c2a797fd.yaml @ b'16aeee430308fd1863d2f9892f09e0d928a0e6f1'
+
+- Add meter rules commands for ``network meter rule create``,
+  ``network meter rule delete``, ``network meter rule list``,
+  and ``network meter rule show``.
+  [Blueprint :oscbp:`neutron-client-metering`]
+
+.. releasenotes/notes/bug-1612136-6111b944569b9351.yaml @ b'8bcfb824c8f2978c9348968d3da1345c45d7b764'
+
+- Add ``--allowed-address`` option to ``port create``, ``port set`` and
+  ``port unset`` commands. Also add ``--no-allowed-address`` option to
+  ``port create`` and ``port set`` commands.
+  [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+.. releasenotes/notes/bug-1647242-fdc39e564372857b.yaml @ b'c46f9dc501441ef449f41e726ec3cfbbe9f3de9d'
+
+- Add ``--deleted`` and ``--changes-since`` options to ``server list``
+  command.
+  [Bug `1647242 <https://bugs.launchpad.net/bugs/1647272>`_]
+
+.. releasenotes/notes/bug-1648087-21dfb7250abfdbe9.yaml @ b'780ce07459f8c196dbf289909c390ff88a380e3f'
+
+- Add ``--project`` and ``--project-domain`` filtering options
+  to ``port list`` command.
+  [Bug `1648087 <https://bugs.launchpad.net/bugs/1648087>`_]
+
+.. releasenotes/notes/bug-1658147-9de9ae222f9db9ae.yaml @ b'4cb56269ad30d0bd59f7685040ab0585f38c3b0f'
+
+- Add ``--domain`` options to the ``user set`` command.
+  Allows specification of domain context when changing users.
+  [Bug `1658147 <https://bugs.launchpad.net/bugs/1658147>`_]
+
+.. releasenotes/notes/support-no-property-in-volume-snapshot-0af3fcb31a3cfc2b.yaml @ b'16aeee430308fd1863d2f9892f09e0d928a0e6f1'
+
+- Add ``--no-property`` option in ``volume snapshot set``.
+  [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+.. releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml @ b'27e0be051714fe11a3b9b5306f2e0a72d95fe2c3'
+
+- Add ``--project`` and ``--project-domain`` option to
+  ``volume snapshot list`` command, in order to filter list result
+  by different project.
+
+
+.. _python-openstackclient_3.8.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1647406-c936581034a1b6e4.yaml @ b'95c8661f86e74c9d5217869a740da11350f1f0eb'
+
+- Allow ``--block-device-mapping`` option to work correctly with
+  ``--volume`` option in ``server create`` command.
+  After :lpbug:`1383338` ``--block-device-mapping`` was ignored if
+  ``--volume`` was present. Block device mappings are now appended
+  to the mapping created by the ``--volume`` option if it is present.
+  The device name of the boot volume specificed in the ``--volume`` option
+  is no longer assumed to be *'vda'* but now uses the hypervisor's boot
+  index to obtain the device name.  This maintains the status quo for
+  **QEMU/KVM** hypervisors but **XEN**, **parallels** and others 
+  *virt types* that have device naming is different from ``vd*``
+  should now also work correctly.
+  [:lpbug:`1497845`]
+  [:lpbug:`1647406`]
+
+.. releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml @ b'4d9da2c40ae02086258cfde852b297754d8085fa'
+
+- Fixed a ``__init__() got an unexpected keyword argument 'project_name'``
+  error in various networking commands when ``help`` or ``--help`` was used.
+  [Bug `1650026 <https://bugs.launchpad.net/bugs/1650026>`_]
+
+.. releasenotes/notes/bug-1655445-96c787e3a51226e0.yaml @ b'0340275fa9b48cda5a5f4015534ca8cbca23b3d2'
+
+- Work around a bug in OpenStackSDK 0.9.11 and 0.9.12 that causes
+  ``quota set --network`` to fail.
+  [Bug `1655445 <https://bugs.launchpad.net/python-openstackclient/+bug/1655445>`_]
+
+.. releasenotes/notes/bug-1656767-36a3d4b9fac335c9.yaml @ b'f353253122ca39aeb092656cea011a06e70103a4'
+
+- Fixed a ``volume qos create`` display mistake in argument of ``specs``.
+  [Bug `1656767 <https://bugs.launchpad.net/python-openstackclient/+bug/1656767>`_]
+
+.. releasenotes/notes/bug-1658582-80a76f6b0af0ca12.yaml @ b'5cf77bb672eeb28327cac8bc0a8227c8b7137819'
+
+- Correctly handle non-admin in ``create trust`` command when looking
+  up role names.
+  [Bug `1658582 <https://bugs.launchpad.net/python-openstackclient/+bug/1658582>`_]
+
+
+.. _python-openstackclient_3.7.0:
+
+3.7.0
+=====
+
+.. _python-openstackclient_3.7.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-auto-and-none-as-nic-parameter-ed23a6e7f99f250d.yaml @ b'ff18e3d0e9307fb505113b467e58bdb62992fb85'
+
+- Added ``auto`` and ``none`` as values for ``--nic`` to
+  the``server create`` command. Specifying ``none`` will not
+  attach a network to the server. Specifying ``auto``
+  will automatically attach a network. Note, v2.37 (or newer)
+  of the Compute API is required for these options.
+  [Bug `1650342 <https://bugs.launchpad.net/bugs/1650342>`_]
+
+.. releasenotes/notes/add-network-qos-rule-22cc1ddd509941db.yaml @ b'6b114cd98f4a1bc95cb8702db02eeb625be6b3e7'
+
+- Add support for Network QoS rule commands:
+  ``network qos rule create``, ``network qos rule delete``,
+  ``network qos rule list``, ``network qos rule show`` and
+  ``network qos rule set``
+  [Bug `1609472 <https://bugs.launchpad.net/bugs/1609472>`_]
+
+.. releasenotes/notes/add-network-qos-rule-types-337e464c6e81f29c.yaml @ b'9e1e7e1c9fde2e60b2f95f3bd000c599a9e1c72a'
+
+- Add support for Network QoS rule type commands:
+  ``network qos rule type list``,
+  [Bug `1612194 <https://bugs.launchpad.net/bugs/1612194>`_]
+
+.. releasenotes/notes/add-overwrite-option-to-router-7c50c8031dab6bae.yaml @ b'4d3cfb9142be8884fa74a6a8b324df869e32ba30'
+
+- Add  ``--router`` and ``--no-router`` options to ``osc router set`` command to
+  modify routes in a router instance.
+  [ Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+.. releasenotes/notes/bp-neutron-client-metering-1ee703a48343ece1.yaml @ b'0fb1378c6ca7a5ea717ee651d64603b0246f6737'
+
+- Add support for network metering commands:
+  ``network meter create``, ``network meter delete``,
+  ``network meter show``, ``network meter list``
+  [Blueprint :oscbp:`neutron-client-metering`]
+
+.. releasenotes/notes/bug-1613964-b3e8d9d828a3822c.yaml @ b'2f2603d90896d0765e1bb2bb1cfb223fdba75835'
+
+- Add ``consistency group add volume`` and ``consistency group remove volume`` commands in volume v2. [Bug `1642238 <https://bugs.launchpad.net/python-openstackclient/+bug/1642238>`_]
+
+.. releasenotes/notes/bug-1641868-97c284e33f944c2d.yaml @ b'2e78c11c8d485195b9ae40b9d00cf3a557aebd6d'
+
+- Add filters ``--agent-type`` and ``--host``
+  to ``network agent list`` command
+  [Bug `1641868 <https://bugs.launchpad.net/bugs/1641868>`_]
+
+.. releasenotes/notes/bug-1648307-a2c6d7698e927449.yaml @ b'af7129cda33dcd4ac784097ddb4f119e145c40d5'
+
+- Add ``--type``, ``--action``, ``--long`` options
+  to ``network rbac list`` command
+  [Bug `1648307 <https://bugs.launchpad.net/bugs/1648307>`_]
+
+.. releasenotes/notes/image-set-to-update-image-membership-68221f226ca3b6e0.yaml @ b'4d3cfb9142be8884fa74a6a8b324df869e32ba30'
+
+- Add support to update image membership with the ``--accept``, ``--reject`` and ``--pending`` options of the ``image set command``.
+
+
+.. _python-openstackclient_3.7.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1652827-f59bbd1b64df958d.yaml @ b'4d3cfb9142be8884fa74a6a8b324df869e32ba30'
+
+- Fix an endpoint version problem with Image endpoints that contained the
+  substring 'v2'.
+  [Bug `1652827 <https://bugs.launchpad.net/bugs/1652827>`_]
+
+.. releasenotes/notes/bug-1654221-a564ab75a6afc332.yaml @ b'd8749f9148f2a78f28e91c58e698779735eae4dc'
+
+- Fix ``--project`` option for ``flavor create`` command when the
+  ID for the new flavor is auto generated.
+  [Bug `1654221 <https://bugs.launchpad.net/bugs/1654221>`_]
+
+.. releasenotes/notes/bug-1655537-20b0eb676afa278f.yaml @ b'024bd3bd660490e458456c28674dcd0ad4ee13c8'
+
+- Fixed a ``'Quota' object is not iterable`` error in the ``quota show`` command
+  that appeared with the initial release of openstacksdk v0.9.11 and v0.9.12.
+  [Bug `1655537 <https://bugs.launchpad.net/bugs/1655537>`_]
+
+.. releasenotes/notes/bug-1656402-88b12760fb2d4ef9.yaml @ b'339af2c20bfe44a772a1e39fc8b769db112b75ce'
+
+- Fix ``floating ip delete`` and ``floating ip show`` to accept IP addresses
+  in addition to IDs to select floating IPs to delete or show.
+  [Bug `1656402 <https://bugs.launchpad.net/bugs/1656402>`_
+
+.. releasenotes/notes/bug-1656572-b40303ae50a41000.yaml @ b'819526591ee2cdbf7f138a08f9c38b9c804e5d31'
+
+- Work around a bug in OpenStackSDK 0.9.11 and 0.9.12 that causes
+  ``quota show --default`` to fail.
+  [Bug `1656572 <https://bugs.launchpad.net/python-openstackclient/+bug/1656572>`_]
+
+.. releasenotes/notes/bug-volume-list-with-project-2dc867c5e8346a66.yaml @ b'51ea68ae948da5d69b262827961ca9ae9118edbc'
+
+- Fix a bug of unable to filter volume list by ``--project``
+  and ``--user`` options in the ``openstack volume list``.
+
+.. releasenotes/notes/speedup-object-save-6bd59e678a31c3e8.yaml @ b'1cdc1319d6cbfc4087551e5bf0a9875c016eca1c'
+
+- Makes ``openstack object save`` much faster when saving an object to disk.
+  [Bug `1654645 <https://bugs.launchpad.net/bugs/1654645>`_]
+
+
+.. _python-openstackclient_3.6.0:
+
+3.6.0
+=====
+
+.. _python-openstackclient_3.6.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/bp-cinder-command-support-82dbadef47454c18.yaml @ b'd083ddb12f4b8eb0d72bb4ff60113cd0904d8c1d'
+
+- Add ``--default`` option to ``volume type list`` command, in
+  order to show which volume type the volume sets as it's
+  default.
+  [Blueprint :oscbp:`cinder-command-support`]
+
+.. releasenotes/notes/bp-cinder-command-support-ff7acc531baae8c3.yaml @ b'7e5a98bca91e0734f3440fdbeb12cd59273cd6a4'
+
+- Add ``--bootable``, ``--non-bootable``, ``--read-only`` and ``--read-write`` options to ``volume create`` command. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+.. releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml @ b'd12aa86f7c4cadb423553d607ae4078f2cb8a962'
+
+- Add ``--name``, ``--ip-version``, ``--project``, ``--project-domain``,
+  ``--share``, ``--no-share`` options to the ``address scope list`` command.
+  [Bug `1636046 <https://bugs.launchpad.net/bugs/1636046>`_]
+
+.. releasenotes/notes/bug-1650342-22cb88ef37a41872.yaml @ b'63377f25fc7dfae151bab2f6e82002a9a1944e93'
+
+- Add ``ploop`` as a valid disk format choice for ``image create`` and ``image set`` commands. [Bug `1650342 <https://bugs.launchpad.net/bugs/1650342>`_]
+
+.. releasenotes/notes/router-gateway-set-01d9c7ffe4461daf.yaml @ b'4a5bf8d2a58fde1d6cbbd2bb27c3eb6fabe59c3a'
+
+- Add support for setting the gateway information in a router,
+  by introducing the new option ``--external-gateway`` in
+  ``router set`` command and clearing the gateway information in a router
+  by introducing ``--external-gateway`` option in ``router unset`` command.
+  [ Blueprint `neutron-client-advanced-router <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-advanced-router>`_]
+
+
+.. _python-openstackclient_3.5.0:
+
+3.5.0
+=====
+
+.. _python-openstackclient_3.5.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-dns-nameserver-overwrite-option-b866baeae12f9460.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Add ``--no-dns-nameserver`` option to ``subnet set`` command.
+  [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+.. releasenotes/notes/add-network-service-provider-c161a4a328a8a408.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Add ``network service provider list`` command.
+
+.. releasenotes/notes/add-port-security-enabled-to-port-set-82b801d21d45e715.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Add ``--enable-port-security`` and ``--disable-port-security``
+  options to ``port set`` and ``port create`` commands.
+  [Blueprint :oscbp:`network-commands-options`]
+
+.. releasenotes/notes/bp-cinder-command-support-413b6d80232f8ece.yaml @ b'4b14f3d0cb26dc89d7b62c70302eefaabc7cf2e3'
+
+- Add ``--type`` and ``--retype-policy`` options to ``volume set`` command.
+  [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+.. releasenotes/notes/bp-cinder-command-support-7e3ae1fb4cd90407.yaml @ b'71e6d444767a29664821ab190e0736088d8ccfba'
+
+- Add ``volume host set`` command, it allows a user to enable or disable a volume host. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+.. releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml @ b'bbfd8cb46bc7493971173f1cbc774ef4697ddfe4'
+
+- Add ``--force`` option to ``volume snapshot delete`` command to allow delete
+  in state other than error or available.
+  [Bug `1597195 <https://bugs.launchpad.net/bugs/1597195>`_]
+
+.. releasenotes/notes/bug-1612136-63aac6377209db38.yaml @ b'df5f12b135f273e3916e7bf300fa7688a180ea02'
+
+- Add ``--dns-name`` option to ``os port create`` and ``os port set`` commands.
+  [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+.. releasenotes/notes/bug-1613231-386b2b1373662052.yaml @ b'ce079d22617f3129bfdf5165b9f124d7cc7dbc2e'
+
+- Add ``--project`` and ``--project-domain`` options to the ``router list``,
+  ``floating ip create`` and ``security group list`` commands.
+  [Bug `1613231 <https://bugs.launchpad.net/bugs/1613231>`_]
+  [Bug `1613629 <https://bugs.launchpad.net/bugs/1613629>`_]
+  [Bug `1610909 <https://bugs.launchpad.net/bugs/1610909>`_]
+
+.. releasenotes/notes/bug-1613964-837196399be16b3d.yaml @ b'1907220113efe9425a6cc7f52ce87dd4e82233c7'
+
+- Add ``consistency group create`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+
+.. releasenotes/notes/bug-1613964-837196399be16b3d.yaml @ b'1907220113efe9425a6cc7f52ce87dd4e82233c7'
+
+- Add ``consistency group delete`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+
+.. releasenotes/notes/bug-1613964-837196399be16b3d.yaml @ b'1907220113efe9425a6cc7f52ce87dd4e82233c7'
+
+- Add ``consistency group show`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+
+.. releasenotes/notes/bug-1613964-86e0afe0e012a758.yaml @ b'4dc78e4265f60356ea453c7f52fcdaeecec58fcb'
+
+- Add ``consistency group set`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+
+.. releasenotes/notes/bug-1614379-d8e2815804d53cef.yaml @ b'47716d1ad32b7c879f6b5736687be1553f6fbfb6'
+
+- Add ``--long``, ``--status``, ``--project``, ``--project-domain``,
+  and ``--router`` options to ``floating ip list`` command.
+  [Bug `1614379 <https://bugs.launchpad.net/bugs/1614379>`_]
+
+.. releasenotes/notes/bug-1614379-da92ded6d19f5ad5.yaml @ b'839c5f7a84b48cecbc80606e894b7906fa01d66b'
+
+- Add ``--port``, ``--fixed-ip-address``, ``--network``,
+  options to ``floating ip list`` command
+  [Bug `1614379 <https://bugs.launchpad.net/bugs/1614379>`_]
+
+.. releasenotes/notes/bug-1618676-04ff0f335b670567.yaml @ b'7357b24d3a63be612aa32c901e15424ff92beca0'
+
+- Add ``--remote-source`` option to ``volume snapshot create`` command to support creating volume snapshot from an existing remote volume snapshot in volume v2. [Bug `1618676 <https://bugs.launchpad.net/python-openstackclient/+bug/1618676>`_]
+
+.. releasenotes/notes/bug-1639231-21823768bd54170a.yaml @ b'a7a0d0c61a6a88e044b781bbc4903cdcfc919e55'
+
+- The  ``image list`` command will now sort by name in ascending order by
+  default. ``--sort`` option will have the default value of ``name:asc``.
+  [Bug `1639231 <https://bugs.launchpad.net/bugs/1639231>`_]
+
+.. releasenotes/notes/bug-1642238-3032c7fe7f0ce29d.yaml @ b'3907137f5824e359bcdcfcdd8ab3d15a83d10bca'
+
+- Add ``consistency group snapshot create``, ``consistency group snapshot delete``, ``consistency group snapshot list`` and ``consistency group snapshot show`` commands in volume v2. [Bug `1642238 <https://bugs.launchpad.net/python-openstackclient/+bug/1642238>`_]
+
+.. releasenotes/notes/bug-1643861-b17ad5dfcb4304ff.yaml @ b'5e070c36a176edf47ec0832ef90636ee6720def7'
+
+- Add ``Is Public`` column to ``volume type list``. [Bug `1643861 <https://bugs.launchpad.net/python-openstackclient/+bug/1643861>`_]
+
+.. releasenotes/notes/bug-1645252-219bfd50c8f04846.yaml @ b'6ca4dc3533d009866f82515c34cb3881f993c750'
+
+- Add ``--name``, ``--status`` and ``--volume`` options
+  to ``volume snapshot list`` command
+  [Bug `1645252 <https://bugs.launchpad.net/bugs/1645252>`_]
+
+.. releasenotes/notes/network-add-qos-policy-a25e868e67142f90.yaml @ b'4132392c2fd8337d18296c33f07c4a89b8a58bda'
+
+- Add QoS support for Network commands.
+  The new parameter ``qos-policy`` is added to ``network create`` and
+  ``network set`` commands. This parameter is the name or the ID of the
+  network QoS policy to attach to this network.
+  [Bug `1627069 <https://bugs.launchpad.net/python-openstackclient/+bug/1627069>`_]
+
+.. releasenotes/notes/rename-snapshot-commands-e0937f7143a4ef55.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Add new commands ``volume snapshot create/delete/list/show/set/unset``. They are used to replace the old commands ``snapshot create/delete/list/show/set/unset``. [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+
+
+.. _python-openstackclient_3.5.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/rename-snapshot-commands-e0937f7143a4ef55.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Deprecate commands ``snapshot create/delete/list/show/set/unset``. [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+
+
+.. _python-openstackclient_3.5.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1619274-e78afd7c12ea2c3d.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Skip password prompt when running commands that do not require auth and user auth values are present except for password. [Bug `1619274 <https://bugs.launchpad.net/python-openstackclient/+bug/1619274>`_] *Fixed in release 3.3.0*
+
+.. releasenotes/notes/bug-1642301-ad04424c80e8fe50.yaml @ b'11a762e03c3d53b45888387f3c5472a37d9d9f68'
+
+- Fix problem with ``--os-auth-type token_endpoint`` that caused exceptions when recent os-client-config version 1.23.0 or newer is installed. [Bug `1642301 <https://bugs.launchpad.net/bugs/1642301>`_] *Fixed in release 3.4.1*
+
+.. releasenotes/notes/bug-1642772-19f53765bef8ee91.yaml @ b'4bce7167338908b082eb8ea946adcd60109e0907'
+
+- Changed the default version of ``OS_IMAGE_API_VERSION`` to ``2``. Image v1 has been deprecated for more than six months and other projects, such as `shade` and `os-client-config` are using Image v2 by default as well. [Bug `1642772 <https://bugs.launchpad.net/bugs/1642772>`_]
+
+
+.. _python-openstackclient_3.4.1:
+
+3.4.1
+=====
+
+.. _python-openstackclient_3.4.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1642301-18b08e0cd4b11687.yaml @ b'61cc5464750e03a44536642cdc493cf81ded2366'
+
+- Fix ``TypeError: __init__() got an unexpected keyword argument 'project_domain_id'``
+  error with non-password authentication types.
+  [Bug `1642301 <https://bugs.launchpad.net/bugs/1642301>`_]
+
+
+.. _python-openstackclient_3.4.0:
+
+3.4.0
+=====
+
+.. _python-openstackclient_3.4.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-ha-to-router-update-6a38a73cc112b2fc.yaml @ b'bae09c3c3fac210f4839a8a51dfb51e2dad69aa7'
+
+- Add support to update high-availability property of
+  a router by adding ``--ha`` and ``--no-ha`` option
+  to ``router set`` CLI.
+  [Bug `1631492 <https://bugs.launchpad.net/bugs/1631492>`_]
+
+.. releasenotes/notes/add-network-qos-policy-b8ad1e408d73c279.yaml @ b'3205dad161c6c7bcaf16f985121217b8cf320af0'
+
+- Add support for Network QoS policies commands:
+  ``network qos policy create``, ``network qos policy delete``,
+  ``network qos policy list``, ``network qos policy show`` and
+  ``network qos policy set``
+  [Bug `1609037 <https://bugs.launchpad.net/bugs/1609037>`_]
+
+.. releasenotes/notes/backup_list_all-projects_option-4bb23e0b9b075cac.yaml @ b'74360e00f51bd6be275ae5e7e5fc0e1ee765b54f'
+
+- Add ``--all-projects`` option to the ``volume backup list`` command to list volume backups across all projects.
+
+.. releasenotes/notes/bp-cinder-command-support-3db775ba331e113d.yaml @ b'daffce3a6a31ac59ee10e3cc8fe421320da1704a'
+
+- Add ``--read-only`` and ``--read-write`` options to ``volume set`` command.
+  [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+.. releasenotes/notes/bp-neutron-client-descriptions-b65dd776f78b5a73.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Add ``--description`` option to ``security group rule create`` command.
+  [Blueprint :oscbp:`network-commands-options`]
+
+.. releasenotes/notes/bp-neutron-client-descriptions-b65dd776f78b5a73.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Add ``--description`` option to ``port set`` and
+  ``port create`` commands.
+  [Blueprint :oscbp:`neutron-client-descriptions`]
+
+.. releasenotes/notes/bug-1566090_64726dc7df5b1572.yaml @ b'8f8a8448a4adc1d250c253738688ff46e6456616'
+
+- ``openstack floating ip`` now provides ``Floating Network`` and
+  ``Project`` to identify to which network and project the
+  floating-ip belongs to.
+  [Bug `1566090 <https://bugs.launchpad.net/bugs/1566090>`_]
+
+.. releasenotes/notes/bug-1612136-051b5f94796e3b51.yaml @ b'66a04abd581e03e5e71a6b755e1b4dce1856ef41'
+
+- Add ``--security-group`` and ``--no-security-group`` options to
+  ``port create``, ``port set`` and ``port unset`` commands.
+  [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+.. releasenotes/notes/bug-1613533-93279179c6f70117.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Add ``--ingress``, ``--egress`` and ``--protocol`` options to
+  ``security group rule list`` command.
+  [Bug `1613533 <https://bugs.launchpad.net/bugs/1613533>`_]
+
+.. releasenotes/notes/bug-1613995-10bb3895d702c063.yaml @ b'2c1282cecf33162b5483f5cb558f98395945380b'
+
+- Add a new column ``status`` and ``--long`` option to the result of the
+  ``os port list`` command.
+  [Bug `1613995 <https://bugs.launchpad.net/bugs/1613995>`_]
+  [Bug `1614321 <https://bugs.launchpad.net/bugs/1614321>`_]
+
+.. releasenotes/notes/bug-1634333-a2b04d33ca39440e.yaml @ b'a1e305641430af48b72c941f87c7ffcc182b3f9a'
+
+- Add support to allow filtering ports via ``--mac-address``
+  option to the ``port list`` command.
+  [Bug `1634333 <https://bugs.launchpad.net/bugs/1634333>`_]
+
+.. releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml @ b'960b2658dc6ab1f82b78dbc531386544d302f09e'
+
+- Add ``--provider-network-type``, ``--provider-physical-network``,  and
+  ``--provider-segment`` options to the ``network list`` command.
+  [Bug `1635580 <https://bugs.launchpad.net/bugs/1635580>`_]
+
+.. releasenotes/notes/bug-1637074-1b0e409f30f715ca.yaml @ b'8ca1cc637013972491744b8318d30e9256bc4165'
+
+- Add ``--long`` option and more columns to the ``hypervisor list`` command.
+  [Bug `1637074 <https://bugs.launchpad.net/bugs/1637074>`_]
+
+.. releasenotes/notes/bug-1637945-f361c834381d409c.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Add ``--name``, ``--enable``, ``--disable`` options to
+  ``router list`` command.
+  [Bug `1637945 <https://bugs.launchpad.net/bugs/1637945>`_]
+
+.. releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml @ b'e07b0e0919784b48dc47ae9cd8836342b8c13480'
+
+- Add ``--name``, ``--status``, ``--volume``, ``--marker`` and ``--limit`` options
+  to ``volume backup list`` command
+  [Bug `1639712 <https://bugs.launchpad.net/bugs/1639712>`_]
+
+.. releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml @ b'57d5f945402681e5f7d62b9ca99fc229927cc784'
+
+- ``rbac_object`` parameter in ``network rbac create`` command now can be a QoS policy name.
+
+.. releasenotes/notes/volume-migrate-command-52cf6edd62fe17a7.yaml @ b'd7c8bb88e4a117d8ab6a53c3a7d14cc7a4105eda'
+
+- Add ``volume migrate`` command. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+
+.. _python-openstackclient_3.4.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/bug-1637365-b90cdcc05ffc7d3a.yaml @ b'0ac4370c09567b80cda84d022068642047576e32'
+
+- Rename the ``--src-group`` and ``--src-ip`` options in the
+  ``security group rule create`` command to ``--remote-group``
+  and ``--remote-ip``.
+  The ``--src-group`` and ``--src-ip`` options are deprecated but still
+  supported, and will be removed in a future release.
+  [Bug `1637365 <https://bugs.launchpad.net/python-openstackclient/+bug/1637365>`_]
+
+
+.. _python-openstackclient_3.4.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1518059-e2dbe6e4b2473f10.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Fix the ``--block-migration`` and ``--shared-migration`` options for
+  ``server migrate`` to send the correct values to the Compute API.
+  [Bug `1518059 <https://bugs.launchpad.net/bugs/1518059>`_]:
+
+.. releasenotes/notes/bug-1607959-a52aa93e3793f28a.yaml @ b'3770ad08b21b5ad7dd5430e810f1618435b269d5'
+
+- A warning message will be shown when an empty password is used
+  for ``user create`` and ``user set`` operations.
+  [Bug `1607959 <https://bugs.launchpad.net/bugs/1607959>`_]
+
+.. releasenotes/notes/bug-1631471-beb0a1c9b4a932cb.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Fix ``router unset --route`` to correctly removed routes.
+  [Bug `1631471 <https://bugs.launchpad.net/bugs/1631471>`_]
+
+.. releasenotes/notes/bug-1634672-7ce577f3adc34eed.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Fix ``--no-allocation-pool`` option for ``subnet set`` command to
+  send the correct value to the Network API.
+  [Bug `1518059 <https://bugs.launchpad.net/bugs/1518059>`_]:
+
+.. releasenotes/notes/cliff-2.3.0-7ead18fae9ceea80.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Cliff 2.3.0: The shell formatter would emit invalid shell variable
+  names for field names that contain colons ('``:``') and dashes ('``-``'),
+  these are now replaced by underscores ('``_``').
+  [Bug `1616323 <https://bugs.launchpad.net/bugs/1616323>`_]
+
+
+.. _python-openstackclient_3.3.0:
+
+3.3.0
+=====
+
+.. _python-openstackclient_3.3.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-network-list-option-to-ports-9d101344ddeb3e64.yaml @ b'554607eb3dab879da8e172eacb72930e54f0acf4'
+
+- Ports can now be listed as per the networks they are
+  connected to by using the ``--network`` option with
+  the ``port list`` CLI.
+  [ Blueprint `network-commands-options <https://blueprints.launchpad.net/python-openstackclient/+spec/network-commands-options>`_]
+
+.. releasenotes/notes/bp-allow-overwrite-set-options-190a9c6904d53dab.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Allow ``--no-fixed-ip`` and ``--no-binding-profile`` options to
+  ``port set`` command to be specified when ``--fixed-ip`` and
+  ``--binding-profile`` are present.  This allows the list of fixed
+  IPs and binding profiles to be cleared and replaced with new values
+  in a single command.
+  [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+.. releasenotes/notes/bp-allow-overwrite-set-options-190a9c6904d53dab.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Add ``--no-allocation-pool`` and ``--no-host-route`` options to
+  ``subnet set`` command that clears the respective values in the
+  specified subnet.  This allows new values to replace the entire
+  list of existing values in a single command for allocation pools
+  and host routes.
+  [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+.. releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml @ b'3ef7e29dd01a848ad08ce1b66deb9c5c3b1a4b1e'
+
+- Add ``volume transfer request create``, ``volume transfer request delete``, ``volume transfer request show`` and ``volume transfer request accept`` commands in volume v1 and v2. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+.. releasenotes/notes/bp-network-command-options-2-e7b13a6a09f5d21e.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Add ``--description`` option to ``network create`` and
+  ``network set`` commands.
+  [Blueprint `network-commands-options <https://blueprints.launchpad.net/python-openstackclient/+spec/network-commands-options>`_]
+
+.. releasenotes/notes/bp-neutron-client-descriptions-a80902b4295843cf.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Add ``--description`` option to ``floating ip create`` command.
+  [Blueprint :oscbp:`neutron-client-descriptions`]
+
+.. releasenotes/notes/bp-neutron-client-descriptions-a80902b4295843cf.yaml @ b'ad5ae83a34e555dabeb2761d3d8f3c7f1dbac2f8'
+
+- Add ``--description`` option to ``router set`` and
+  ``router create`` commands.
+  [Blueprint :oscbp:`network-commands-options`]
+
+.. releasenotes/notes/bp-routed-networks-3b502faa5cd96807.yaml @ b'256ec66f79f98b41497e8937911604bac7ddeabb'
+
+- Add ``network segment create``, ``network segment delete`` and ``network segment set`` commands. In addition, the ``network segment list`` and ``network segment show`` commands are no longer beta commands and the ``--network-segment`` option on the ``subnet create`` command is no longer a beta command option. [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
+
+.. releasenotes/notes/bp-support-no-property-in-aggregate-b74a42e00a65d14a.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Add ``--no-property`` option to ``aggregate set`` command.
+  This allows the property list to be cleared and replaced with
+  new values in a single command.
+  [Blueprint `support-no-property-in-aggregate <https://blueprints.launchpad.net/python-openstackclient/+spec/support-no-property-in-aggregate>`_]
+
+.. releasenotes/notes/bug-1204956-af47c7f34ecc19c3.yaml @ b'6f326acd260d035cb024f0c5e3ef2237277d8b37'
+
+- Supported to fetch network project default quota with command ``quota show --default``. [Bug `1204956 <https://bugs.launchpad.net/neutron/+bug/1204956>`_]
+
+.. releasenotes/notes/bug-1578819-d1efccfefb18356d.yaml @ b'9c473f475d2bb7adadc65a7525b93db84f10bef9'
+
+- Add ``--internal``, ``--name``, ``--project`` and ``--project-domain``,
+  ``--enable`` and ``--disable``, ``--share`` and ``--no share``, ``--status``
+  options to the ``network list`` command.
+  [Bug `1578819 <https://bugs.launchpad.net/bugs/1578819>`_]
+
+.. releasenotes/notes/bug-1607972-a910a9fbdb81da57.yaml @ b'78312ca9afea22f6511f2421dccb0736f394e9c8'
+
+- Add ``--name`` option to command ``object create`` for uploading a file and renaming it. [Bug `1607972 <https://bugs.launchpad.net/bugs/1607972>`_]
+
+.. releasenotes/notes/bug-1609767-0602edc4408c2dc6.yaml @ b'6fba7163e85a436d1fe0660d9932a53d06b1a343'
+
+- Support to update ``per_volume_gigabytes``, ``backup_gigabytes`` and ``backups`` quota in ``quota set`` command. [Bug `1609767 <https://bugs.launchpad.net/python-openstackclient/+bug/1609767>`_]
+
+.. releasenotes/notes/bug-1610161-7c34c7b735701bd4.yaml @ b'e2fc436d53f53d0993fc0b9dd29f402e6c7f8bc1'
+
+- Add ``--ha`` option to ``router create`` command.
+  [Bug `1610161 <https://bugs.launchpad.net/bugs/1610161>`_]
+
+.. releasenotes/notes/bug-1610883-38929f6fc2eefc9a.yaml @ b'5ec435e706d137afb714cfd5c5ddbd40d8107a9e'
+
+- Add ``--project``, ``--project-domain``, ``--network``, ``--gateway``,
+  ``--name`` and ``--subnet-range`` options to the ``subnet list``  command.
+  [Bug `1610883 <https://bugs.launchpad.net/bugs/1610883>`_]
+
+.. releasenotes/notes/bug-1612484-e8605ad8966a455e.yaml @ b'6986a32e1cd6d0c0bdf973e5d4e4bcb3d1f45235'
+
+- Add ``--limit`` option to ``volume list`` command in volume v1,
+  add ``--limit`` and ``--marker`` options to ``volume list``
+  command in volume v2.
+  [Bug `1612484 <https://bugs.launchpad.net/bugs/1612484>`_]
+
+.. releasenotes/notes/bug-1613261-290a64080fead6c0.yaml @ b'ddf84429f297b34ce7067250d834ea897e37f37c'
+
+- Add ``volume backup set`` commands in volume v2. [Bug `1613261 <https://bugs.launchpad.net/python-openstackclient/+bug/1613261>`_]
+
+.. releasenotes/notes/bug-1613597-b1545148b0755e6f.yaml @ b'81431d24a9f94f56c4c39cb12bf846871f6230d8'
+
+- Add ``volume service set`` commands in volume v1 and v2. [Bug `1613597 <https://bugs.launchpad.net/python-openstackclient/+bug/1613597>`_]
+
+.. releasenotes/notes/bug-1613926-2d0e405831c0b5a9.yaml @ b'5ec435e706d137afb714cfd5c5ddbd40d8107a9e'
+
+- Add ``--share``, ``--no-share``, ``--project``, ``--project-domain``,
+  ``--default``, ``--no-default``, ``--name`` and ``--address-scope``
+  options to the ``subnet pool list`` command.
+  [Bug `1613926 <https://bugs.launchpad.net/bugs/1613926>`_]
+
+.. releasenotes/notes/bug-1613964-e5760f4825f1e043.yaml @ b'8d63b8b263ca4011761b062331d53d9b53b5031d'
+
+- Add ``consistency group list`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+
+.. releasenotes/notes/bug-1614385-460b5034ba372463.yaml @ b'96a8ed435c7e55633c00dbb1283477ff11cf35f9'
+
+- Support listing the specified server's ports by new option ``--server`` of ``port list`` command. [Bug `1614385 <https://bugs.launchpad.net/python-openstackclient/+bug/1614385>`_]
+
+.. releasenotes/notes/bug-1614458-c42be5738f447db8.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Adds ``--description`` option to ``subnet create`` and
+  ``subnet set`` commands.
+  [Bug `1614458 <https://bugs.launchpad.net/bugs/1614458>`_]
+
+.. releasenotes/notes/bug-1614823-e89080342f25f2c0.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Adds ``--description`` option to ``subnet pool create``
+  and ``subnet pool set`` commands.
+  [Bug `1614823 <https://bugs.launchpad.net/bugs/1614823>`_]
+
+.. releasenotes/notes/bug-1627913-2adf4182977e5926.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Add ``--source-replicated``, ``--consistency-group``, ``--hint`` and
+  ``--multi-attach`` options to ``volume create`` command in volume v2.
+  Make ``--size`` optional when ``--snapshot``, ``--source`` or
+  ``source-replicated`` options are present.
+  [Bug `1627913 <https://bugs.launchpad.net/python-openstackclient/+bug/1627913>`_]
+
+.. releasenotes/notes/subnet-service-type-8d9c414732e474a4.yaml @ b'cf9ad08ab6fd5e6ed5f68208a39b0014b0af5f8a'
+
+- Add ``--service-type`` option to the ``subnet create``,
+  ``subnet set``, ``subnet unset``, and ``subnet list`` commands.
+  [ Blueprint `service-subnets <https://blueprints.launchpad.net/neutron/+spec/service-subnets>`_]
+
+
+.. _python-openstackclient_3.3.0_Security Issues:
+
+Security Issues
+---------------
+
+.. releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Mask passwords when ``--debug`` or ``-vv`` options are used.
+  [Bug `1630822 <https://bugs.launchpad.net/python-openstackclient/+bug/1630822>`_]
+
+
+.. _python-openstackclient_3.3.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1535704-d6f013bfa22ab668.yaml @ b'6a914d0056e810e1ef37eaf4f01cd5c85217aba6'
+
+- Add ``--bootable`` and ``--non-bootable`` options to ``os volume set``
+  command to mark volume as bootable or non-bootable.
+  [Bug `1535704 <https://bugs.launchpad.net/bugs/1535704>`_]
+
+.. releasenotes/notes/bug-1588171-61214d0ea482988c.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Update novaclient ``DEFAULT_API_VERSION`` from 2.0 to 2.1
+  [Bug `1588171 <https://bugs.launchpad.net/bugs/1588171>`_]
+
+.. releasenotes/notes/bug-1609233-90b2ddf8d941050e.yaml @ b'762f2f2c34814b8bfc615696918d8cb49b93a1dd'
+
+- Fix the ``--class`` option in ``quota set`` and ``quota show``
+  commands to not perform a project lookup in Identity.
+  [Bug `1609233 <https://bugs.launchpad.net/bugs/1609233>`_]
+
+.. releasenotes/notes/bug-1620922-7f27942dc00f7108.yaml @ b'5231ade27c8a08e3d7fd5573d4dda6fa47d0ae67'
+
+- Do not show ``os-volume-type-access:is_public`` property which is the same as ``is_public`` property of volume type object. [Bug `1620922 <https://bugs.launchpad.net/python-openstackclient/+bug/1620922>`_]
+
+.. releasenotes/notes/bug-1622565-2e715aff8b054401.yaml @ b'5ec435e706d137afb714cfd5c5ddbd40d8107a9e'
+
+- Fix ``--long`` option in ``router list`` command for deployments without
+  the ``router_availability_zone`` extension is not enabled.
+  [Bug `1622565 <https://bugs.launchpad.net/bugs/1622565>`_]
+
+.. releasenotes/notes/bug-1624085-7cf296649277f405.yaml @ b'5ec435e706d137afb714cfd5c5ddbd40d8107a9e'
+
+- Fix missing ``_username`` attribute error in ``server ssh`` command. [Bug `1624085 <https://bugs.launchpad.net/python-openstackclient/+bug/1624085>`_]
+
+
+.. _python-openstackclient_3.12.1:
+
+3.12.1
+======
+
+.. _python-openstackclient_3.12.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1711301-633255f813c71d2a.yaml @ b'8eced505329a32533b1154700302780ca5af51ef'
+
+- Fix occurrences of the ``network agent delete`` command failing with newer
+  releases of python-openstacksdk.
+  [Bug `1711301 <https://bugs.launchpad.net/python-openstackclient/+bug/1711301>`_]
+
+.. releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml @ b'b9c5094ede503109955eb90fe0007e343f7bb903'
+
+- Fix the ``project purge`` command to correctly delete only images owned by the
+  specified project ID when run by an administrative user.
+  [Bug `1717130 <https://bugs.launchpad.net/python-openstackclient/+bug/1717130>`_]
+
+.. releasenotes/notes/bug-1732938-868963acedaa307e.yaml @ b'8eced505329a32533b1154700302780ca5af51ef'
+
+- Remove the client-side check for valid ``--policy`` values in the
+  ``server group create`` command.  Specify ``--os-compute-api-version 2.15``
+  or higher for the ``soft-affinity`` or ``soft-anti-affinity`` policy.
+  [Bug `1732938 <https://bugs.launchpad.net/python-openstackclient/+bug/1732938>`_]
+
+
+.. _python-openstackclient_3.12.0:
+
+3.12.0
+======
+
+.. _python-openstackclient_3.12.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-is-default-to-network-qos-policy-89b11d4df032a789.yaml @ b'c17819ab58db7ded30644d63575d47ee3c963ada'
+
+- Add ``--default``  and ``--no-default`` options to
+  ``network qos policy create`` and ``network qos policy set``
+  comamnds.
+  [Bug `1639220 <https://bugs.launchpad.net/bugs/1639220>`_]
+
+.. releasenotes/notes/add-virtio-forwarder-vnic-type-bad939c6a868b9e9.yaml @ b'cf5dfa77e17d273aaebca21a0b44902d587fac04'
+
+- The ``virtio-forwarder`` VNIC type has been added as another option for
+  setting the ``--vnic-type`` property on the ``port set`` and
+  ``port create`` commands. This requests a low-latency virtio port inside
+  the instance, likely backed by hardware acceleration. Currently the
+  Agilio OVS external plugin provides support for this, with support from
+  other vendors following soon.
+
+.. releasenotes/notes/bp-network-l3-adv-commands-cc1df715a184f1b2.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Add  ``network agent add router`` and ``network agent remove router``
+  commands for adding/removing routers to network l3 agents.
+  [Blueprint :oscbp:`network-l3-commands`]
+
+.. releasenotes/notes/bp-network-l3-adv-commands-cc1df715a184f1b2.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Add ``--router`` option to ``network agent list`` to filter by router,
+  and ``--agent`` option to ``router list`` command to filter by agent.
+  [Blueprint :oscbp:`network-l3-commands`]
+
+.. releasenotes/notes/bp-neutron-client-tag-ff24d13e5c70e052.yaml @ b'57e5840710c3b2b74d31bfd6a0da739e0fc747ed'
+
+- Added support for ``tags`` to the following resources:
+  ``network``, ``subnet``, ``port``, ``router`` and ``subnet pool``.
+  [Blueprint :oscbp:`neutron-client-tag`]
+  
+  - Add ``--tag`` and ``--no-tag`` options to corresponding "create" commands.
+  - Add ``--tag`` and ``--no-tag`` options to corresponding "set" commands.
+  - Add ``--tag`` and ``--all-tag`` options to corresponding "unset" commands.
+    (``network unset`` command is introduced to support the tag operation)
+  - Add ``--tags``, ``--any-tags``, ``--not-tags`` and ``--not-any-tags``
+    options to corresponding "list" commands.
+
+.. releasenotes/notes/bug-1584596-5b3109487b451bec.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Add command ``openstack project purge`` to clean a project's resources.
+  [Bug `1584596 <https://bugs.launchpad.net/bugs/1584596>`_]
+
+.. releasenotes/notes/bug-1614121-a3c5b6892074d5ae.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Added ``--egress`` and ``--ingress`` options to
+  ``network qos rule create`` and ``network qos rule set`` commands.
+  This adds directionality to Network QoS ``bandwidth-limit`` rule type.
+  [Bug `1614121 <https://bugs.launchpad.net/python-openstackclient/+bug/1614121>`_]
+
+.. releasenotes/notes/bug-1640086-21d7e5f2ce18f53c.yaml @ b'6962cc963e6e17e709524ecf6a395e2d0c8b8370'
+
+- Add ``--human-readable`` option to ``image show`` to display
+  image size in human readable format (such as K, M, G, T,..)
+  [Bug `1640086 <https://bugs.launchpad.net/bugs/1640086>`_]
+
+.. releasenotes/notes/bug-1667294-f92efa49627eb00a.yaml @ b'eb793dc8c6a8bd30e612f19f30808528b10eb344'
+
+- Add ``--default-quota`` option to ``subnet pool create``
+  and ``subnet pool set`` commands.
+  [Bug `1667294 <https://bugs.launchpad.net/python-openstackclient/+bug/1667294>`_]
+
+.. releasenotes/notes/bug-1684989-3bda158a822d2f73.yaml @ b'1ae904a4912494b3d0ac87f22aaf958129744548'
+
+- Add ``--data-plane-status`` option to ``port set`` and ``port unset`` commands. [Bug `1684989 <https://bugs.launchpad.net/bugs/1684989>`_]
+
+.. releasenotes/notes/bug-1698390-0df8f0ec4fe354de.yaml @ b'77ff011ced18260242224a7317aba92d53ff1455'
+
+- Added the ``--domain`` option to the ``identity provider create`` command to
+  associate an existing domain with an identity provider on its creation.
+  
+  [Bug `1698390 <https://bugs.launchpad.net/python-openstackclient/+bug/1698390>`_]
+
+.. releasenotes/notes/bug-1698742-66d9d4e6c7ad274a.yaml @ b'bca8d57eb3963beb74baa5d75e61954c610369d0'
+
+- Add ``--name`` and ``--status`` options to ``image list`` command
+  to filter images based on name and status respectively.
+  [Bug `1698742 <https://bugs.launchpad.net/bugs/1698742>`_]
+
+.. releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml @ b'470a1f1acfe261357fc3125b2db3bc6ec10c654e'
+
+- Add ``--user`` and ``--type`` option to ``credential list`` command
+  to filter list result by different user or type.
+
+.. releasenotes/notes/object-stdout-db76cc500948b0e8.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Add support for streaming Swift objects to stdout when using the ``object
+  save`` command by specifying ``-`` as a file name: ``--filename -``.
+
+.. releasenotes/notes/skip-name-lookups-9f499927173c1eee.yaml @ b'2689984ba71fa0be25d2368277f33f2fb5c41266'
+
+- Add ``--no-name-lookup`` option to ``server list`` command to skip the lookup of
+  flavor and image names.  This can save a significant amount of time on clouds with
+  a large number of images.  ``-n`` is an alias for this option.
+
+
+.. _python-openstackclient_3.12.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1657956-977a615f01775288.yaml @ b'6aceca218af7d1d2c708fde48f1a5f2b798bc421'
+
+- Change column name ``Display Name`` to ``Name`` in ``volume list`` output.
+  Current ``volume list --name`` command uses ``display_name`` as search_opts
+  to send to cinder API, and show the result table with ``Display Name``
+  as column title. Replace all ``Display Name`` by ``Name`` to be consistent
+  with other list commands.
+  
+  Support a mapping for volume list -c ``Display Name`` (Volume v1 and v2)
+  and volume create/show -c ``display_name`` (Volume v1) to maintain backward
+  compatibility until the next major release.
+  [Bug `1657956 <https://bugs.launchpad.net/python-openstackclient/+bug/1657956>`_]
+
+.. releasenotes/notes/bug-1658189-d2b390ad74c96c79.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Make the ``role assignment list`` command callable without administrator
+  permissions if restricted to the user's own project with the ``--project`` option.
+  [Bug `1658189 <https://bugs.launchpad.net/python-openstackclient/+bug/1658189>`_]
+
+.. releasenotes/notes/bug-1667266-6497727abc2af9a5.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Clarify the ``--block-device-mapping`` option of the ``server create``
+  command: fix ValueError when the ``--block-device-mapping`` option's
+  argument is in the wrong format; support creating a block device from
+  a snapshot; add details to the help output about the option format.
+  [Bug `1667266 <https://bugs.launchpad.net/python-openstackclient/+bug/1667266>`_]
+
+.. releasenotes/notes/bug-1687814-743ad8418923d5e3.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Allow the ``--security-group`` option from the ``server create`` command
+  to be specified by name or ID.  This also checks that the security group exist
+  before creating the server.
+  [Bug `1687814 <https://bugs.launchpad.net/python-openstackclient/+bug/1687814>`_]
+
+.. releasenotes/notes/bug-1689233-c3f98e159c75374e.yaml @ b'acc2d106abfb4fed0ff5d0d0c246d69f9ea1758b'
+
+- Raise exact exception when extension don't exist in ``extension show``
+  command, and keep the column display order consist in ``extension list``
+  with and without ``--long`` option.
+  [Bug `1689233 <https://bugs.launchpad.net/python-openstackclient/+bug/1689233>`_]
+
+.. releasenotes/notes/bug-1696111-e2cf9233fa872eb7.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Fixed an issue where a trust could not be created if multiple roles had
+  the same name. A role's ID is now sent to the identity service instead.
+  [Bug `1696111 <https://bugs.launchpad.net/keystone/+bug/1696111>`_]
+
+.. releasenotes/notes/bug-1704097-8ff1ce1444b81b04.yaml @ b'1f2295cf6531b589de4f6d78c5d10f1c31537bb7'
+
+- Fix an issue with the ``--domain`` option when used with the ``project show``,
+  ``user show`` and ``user set`` commands.  The domain filter did not work when
+  the login user's project name or user name is the same as the requested resource
+  name in the specified domain.
+  [Bug `1704097 <https://bugs.launchpad.net/python-openstackclient/+bug/1704097>`_]
+
+.. releasenotes/notes/image_set_visibility-babf4ff2f687d465.yaml @ b'3468ea1ca429e8b6403ae5f989cfed521d8f5690'
+
+- Add ``--community`` and ``--shared`` options to the ``image create`` and ``image set`` commands to allow image owners to share images across multiple projects without explicitly creating image members. “Community images” will not appear in user’s default image listings.
+
+.. releasenotes/notes/remove-unsupported-set-vlan-transparent-eeff412264ae7c09.yaml @ b'2b66c71a7c2798dc1f9149574d54062b9086a01a'
+
+- Remove ``--transparent-vlan`` and ``--no-transparent-vlan``
+  from ``network set``, because updating ``vlan-transparent``
+  is not supported in Neutron.
+  [Bug `1691776 <https://bugs.launchpad.net/python-openstackclient/+bug/1691776>`_]
+
+
+.. _python-openstackclient_3.11.0:
+
+3.11.0
+======
+
+.. _python-openstackclient_3.11.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1688194-bb008b65267a1169.yaml @ b'c69304e3d365dc2c67fab298eba0b9097d3819da'
+
+- Fix issue in ``port list`` command when no Compute endpoint is in the
+  Service Catalog.
+  [Bug `1688194 <https://bugs.launchpad.net/bugs/1688194>`_]
+
+
+.. _python-openstackclient_3.10.0:
+
+3.10.0
+======
+
+.. _python-openstackclient_3.10.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-network-flavor-profile-e7cc5b353c3ed9d9.yaml @ b'7ef1e9ea96ef15b63304a6bccaf30f8c269f2b76'
+
+- Add support for Network Flavor Profile commands:
+  ``network flavor profile create``, ``network flavor profile delete``,
+  ``network flavor profile list``, ``network flavor profile show`` and
+  ``network flavor profile set``
+  [Blueprint :oscbp:`neutron-client-flavors`]
+
+.. releasenotes/notes/add-qos-policy-list-options-9ba1ae731a88e7ac.yaml @ b'9fd3dba11e5fc60023a9c332cfb76b42d38adf05'
+
+- Add ``--share``, ``--no-share``, ``--project``, ``--project-domain`` options to ``qos policy list`` command. [Blueprint `network-commands-options <https://blueprints.launchpad.net/python-openstackclient/+spec/network-commands-options>`_]
+
+.. releasenotes/notes/add-quota-list-command-0d865fac61db2430.yaml @ b'58591d3c37c0265d8775f881271ba4d987e5ffb6'
+
+- Add ``quota list`` command with ``--compute``, ``--volume``
+  and ``--network`` options.
+  [Blueprint `quota-list <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-quota>`_]
+
+.. releasenotes/notes/allow-to-add-remove-vm-ports-273593d7cc1982de.yaml @ b'21510ac1a94eeb8de218a0edfe81db5ef0437249'
+
+- Add ``server add port`` and ``server remove port`` commands which enable to
+  add/remove ports to/from a server
+  [Bug `1678137 <https://bugs.launchpad.net/python-openstackclient/+bug/1678137>`_]
+
+.. releasenotes/notes/allow-to-create-legacy-router-cb4dcb44dde74684.yaml @ b'53ba05325ad5e580e62addb7f4b405b96ad01d80'
+
+- Add ``--no-ha`` option to the ``router create`` command
+  [Bug `1675514 <https://bugs.launchpad.net/python-openstackclient/+bug/1675514>`_]
+
+.. releasenotes/notes/allow-to-specify-vm-ip-to-publish-85f7207740c0cc8d.yaml @ b'f5527877bb6dab09757b6692460bcc376b7d5ec3'
+
+- Add ``--fixed-ip-address`` option to the ``server add floating ip`` command
+  [Bug `1624524 <https://bugs.launchpad.net/python-openstackclient/+bug/1624524>`_]
+
+.. releasenotes/notes/allow-to-vm-ip-to-add-7721ba64b863fa77.yaml @ b'7f9814860ad739e25b82898176d26c7b788e8e33'
+
+- Add ``--fixed-ip-address`` option to the ``server add fixed ip`` command
+  [Bug `1678140 <https://bugs.launchpad.net/python-openstackclient/+bug/1678140>`_]
+
+.. releasenotes/notes/bp-extension-show-6f7e31a27dad0dc9.yaml @ b'9915efdd0abebd91a3f05a242e0e20bbd5d5efa9'
+
+- Added ``extension show`` command to display the details of an extension.
+  Currently works only for network extensions.
+  [Blueprint `extension-show <https://blueprints.launchpad.net/python-openstackclient/+spec/extension-show>`_]
+
+.. releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml @ b'f4fd8f6e31dcc177b56d1e618cdefef728d09157'
+
+- Add network dhcp-agent related commands ``network agent add network``,
+  ``network agent remove network``, ``network agent list --network`` and
+  ``network list --agent`` for adding/removing network to dhcp agent.
+  [Blueprint :oscbp:`network-dhcp-adv-commands`]
+
+.. releasenotes/notes/bp-support-multi-add-remove-9516f72cfacea11a.yaml @ b'ef5a7caf85bd6169701371da67029457abdaf47f'
+
+- Add support to add/remove multi users by ``group add/remove user`` command.
+  [Blueprint  :oscbp:`support-multi-add-remove`]
+
+.. releasenotes/notes/bug-1549410-8df3a4b12fe13ffa.yaml @ b'dee22d8faa0c8a0da1d6ff62c0997c2cc770b759'
+
+- Add ``--private-key`` option for ``keypair create`` command to specify the
+  private key file to save when a keypair is created, removing the need to
+  copy the output and paste it into a new file. This is a convenient way
+  to save private key in OSC interactive mode.
+  [Bug `1549410 <https://bugs.launchpad.net/python-openstackclient/+bug/1549410>`_]
+
+.. releasenotes/notes/bug-1596818-d4cd93dd4d38d3d6.yaml @ b'6c1b03bf7354fe39d61bb9cf93d2491bbb5ebb16'
+
+- Add ``--sort`` support to ``project list`` by sorting items in client side
+  By default project list will be sorted by name.
+  [Bug `1596818 <https://bugs.launchpad.net/bugs/1596818>`_]
+
+.. releasenotes/notes/bug-1612136-ec240349a933db12.yaml @ b'5ff2cfd042de7afc4323a3b306ff5be1882fba46'
+
+- Add ``--qos-policy`` option to ``port create``,  ``port set`` and
+  ``port unset`` commands.
+  [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+.. releasenotes/notes/bug-1612898-bea3b68251d12d81.yaml @ b'8549071363805a9eef815dd2429b6b860db11a2c'
+
+- Add ``--network`` and ``--port`` options to ``server create`` command
+  as alternatives to ``--nic`` option.
+  [Bug `1612898 <https://bugs.launchpad.net/bugs/1612898>`_]
+
+.. releasenotes/notes/bug-1627555-3b47eba215e35b3c.yaml @ b'49f6032b699804b1b0ed56137ab14ba266251157'
+
+- The ``project list`` command lists all projects when called by an
+  admin user.  For non-admin users it will now list projects for the
+  authenticated user instead of exiting with an authorization failure.
+  The ``--my-projects`` option has also been added to the ``project list``
+  command to allow admin users to list their own projects.
+  [Bug `1627555 <https://bugs.launchpad.net/bugs/1627555>`_]
+
+.. releasenotes/notes/bug-1642030-166b2b28c8adf22e.yaml @ b'9915efdd0abebd91a3f05a242e0e20bbd5d5efa9'
+
+- Add ``server event list`` and ``server event show`` commands.
+  
+  A server event is the event record of actions performed on a server,
+  including: event type(create, delete, reboot and so on),
+  event result(success, error), start time, finish time and others.
+  [Bug `1642030 <https://bugs.launchpad.net/python-openstackclient/+bug/1642030>`_]
+
+.. releasenotes/notes/floating-ip-set-unset-port-28e33875937b69cf.yaml @ b'763c8c5670f238920398165e670592e006213f32'
+
+- Add ``floating ip set`` and ``floating ip unset`` commands.
+  [:lpbug:`1560297`]
+
+.. releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml @ b'b51310a4bb5997137a4b6c0cf3517f481e178474'
+
+- Add ``network flavor add profile`` and ``network flavor remove profile`` commands.
+  [Blueprint :oscbp:`neutron-client-flavors`]
+
+
+.. _python-openstackclient_3.10.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/bug-1633582-df2bee534c2da7fc.yaml @ b'9915efdd0abebd91a3f05a242e0e20bbd5d5efa9'
+
+- ``volume transfer request accept`` has been changed to move the ``auth-key``
+  positional argument to a requried option ``--auth-key``.  This leaves
+  the transfer request ID as the only positional arguemnt, as per the
+  OpenStackClient command format.  The old format is still functional, but is
+  deprecated and will be removed in the next major release.
+
+
+.. _python-openstackclient_3.10.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1633582-df2bee534c2da7fc.yaml @ b'9915efdd0abebd91a3f05a242e0e20bbd5d5efa9'
+
+- Fix ``volume transfer request accept`` to not fail the transfer request
+  name/ID lookup for non-admin users as the Volume API does not allow non-admin
+  users access to transfers in other projects.
+  [Bug `1633582 <https://bugs.launchpad.net/python-openstackclient/+bug/1633582>`_]
+
+.. releasenotes/notes/bug-1633582-df2bee534c2da7fc.yaml @ b'9915efdd0abebd91a3f05a242e0e20bbd5d5efa9'
+
+- Change the output column order in ``volume transfer request list`` to have
+  ``ID`` followed by ``Name`` then the remaining columns.
+
+.. releasenotes/notes/bug-1659894-4518b10615498ba9.yaml @ b'1c49a1f01da73b8eed701809de88b408e738dfed'
+
+- Now the positional parameter ``<snapshot-name>`` of ``volume snapshot create``
+  command is no longer optional, it should be always present.
+  [Bug `1659894 <https://bugs.launchpad.net/bugs/1659894>`_]
+
+.. releasenotes/notes/bug-1659967-644a8ee3621c9e81.yaml @ b'888022f8c0a2911a03fc682fdbe4c68c35a27db7'
+
+- ``security group list`` command now can display project IDs in the ``Project`` column
+  of the command output.
+  [Bug `1659967 <https://bugs.launchpad.net/bugs/1659967>`_]
+
+.. releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml @ b'fe59e339ae6dd6a5e9075773fb5c2a0fea9c2e53'
+
+- Allow users to create centralized (distributed=False)
+  routers using the ``--centralized`` option in ``router create``.
+  Without this, routers are created based on the default
+  neutron configuration of the deployment, which, for example,
+  could be 'distributed'.
+  [Bug `1664255 <https://bugs.launchpad.net/bugs/1664255>`_]
+
+.. releasenotes/notes/bug-1670707-c4799fbed39ef75b.yaml @ b'f1345dc06f91177ced17f102bcdaaa126fe12568'
+
+- Add ``--mac-address`` option to ``port set`` command.
+  [Bug `1670707 <https://launchpad.net/bugs/1670707>`_]
+
+.. releasenotes/notes/bug-1672634-ef754cb5109dd0f2.yaml @ b'853ea5ab59e5d7845d389e46527038575c3c170c'
+
+- Narrow acceptable negative response codes for ``group contains user``
+  [Bug `1672634 <https://bugs.launchpad.net/python-openstackclient/+bug/1672634>`_]
+
+.. releasenotes/notes/bug-1677236-7de9d11c3f0fb5ed.yaml @ b'61cde9c8e85182073b53e3736f8568f2a6d1453c'
+
+- Fix creating a server with a block-device-mapping when volume_size
+  is empty.
+  [Bug `1677236 <https://bugs.launchpad.net/bugs/1652827>`_]
+
+
+.. _python-openstackclient_3.9.0:
+
+3.9.0
+=====
+
+.. _python-openstackclient_3.9.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-network-auto-allocated-topology-481580f48840bfc4.yaml @ b'1169434f42a751ca9ef37fed2fa2fd04fe8b6f8b'
+
+- Add support for the ``network auto allocated topology`` command for
+  creating and deleting auto allocated topologies.
+  [Blueprint :oscbp:`network-auto-allocated-topology`]
+
+.. releasenotes/notes/add-no-property-f97e4b2f390cec06.yaml @ b'1e739d7aebe53d38038b9f6172eb08916a7dd23c'
+
+- Add support to clear/overwrite all flavor properties using
+  ``--no-property`` option with ``flavor set`` command.
+  [Blueprint  :oscbp:`allow-overwrite-set-options`]
+
+.. releasenotes/notes/add-volume-host-failover-8fc77b24533b7fed.yaml @ b'55195cec46fadd88f6151783b1e17557d5e94940'
+
+- Add ``volume host failover`` command.
+  [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+.. releasenotes/notes/bug-1634799-1322227c9b0188ca.yaml @ b'e0e46bca093984926de11559e312d1f1fcade108'
+
+- Add ``--fixed-ip`` option to the ``port list`` command.
+  [Bug `1634799 <https://bugs.launchpad.net/bugs/1634799>`_]
+
+.. releasenotes/notes/bug-1651117-a1df37e7ea939ba4.yaml @ b'b2fd8ba869cd4b8e927118f7712d0ed7fb60309f'
+
+- Add ``--encryption-provider``, ``--encryption-cipher``, ``--encryption-key-size``
+  and ``--encryption-control-location`` options to ``volume type set`` and
+  ``volume type create`` commands.
+  Add ``--encryption-type`` option to ``volume type unset``, ``volume type list``
+  and ``volume type show`` commands.
+  [Bug `1651117 <https://bugs.launchpad.net/bugs/1651117>`_]
+
+.. releasenotes/notes/bug-1666780-c10010e9061689d3.yaml @ b'20429bd5c624399578cb7217e582eb86068114c6'
+
+- Add ``--group`` option to the ``command list`` command to filter the
+  commands by group name: ``openstack command list --group volume`` will
+  list all Volume commands for the selected API version.  Use
+  ``--os-XXXX-api-version`` to select a specific API version for the desired APIs.
+  
+  This provides an alternative to searching help output to list the comamnds
+  available for specific APIs.  Note that the ``--group`` argument is used as
+  a simple substring search in the Command Group column.
+  [Bug `1666780 <https://bugs.launchpad.net/python-openstackclient/+bug/1666780>`_]
+
+.. releasenotes/notes/change-098377fd53cce7a0.yaml @ b'4d5f2c3925068fe49748e05a47c5c9c7e7999b3c'
+
+- Added support for Volume API v3 for the following block storage command
+  resources: ``consistency group``, ``consistency group snapshot``,
+  ``volume``, ``volume backup``, ``volume host``, ``volume snapshot``,
+  ``volume type``, ``volume qos``, ``volume service``,
+  ``volume transfer request``. Note that microversion support for Volume API
+  v3 is not yet implemented, each command will assume the API version is
+  ``3.0``.
+
+.. releasenotes/notes/network-flavor-command-support-afe3a9da962a09bf.yaml @ b'3907389785055e4599907dca39ae2c2bc0e78497'
+
+- Add ``network flavor create``,  ``network flavor delete``,
+  ``network flavor list``, Add ``network flavor show`` and
+  ``network flavor set`` command
+  [Blueprint :oscbp:`neutron-client-flavors`]
+
+.. releasenotes/notes/support-no-property-in-volume-811e67ff4a199eb6.yaml @ b'40ec7a9c96f4ce4071e47e5bf0c249aa77b5b2ee'
+
+- Add ``--no-property`` option in ``volume set``, this removes all properties from a volume.
+  [Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+
+.. _python-openstackclient_3.9.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1499657-eeb260849febacf3.yaml @ b'20429bd5c624399578cb7217e582eb86068114c6'
+
+- Fix ``--parents`` and ``--children`` options in ``project show`` command.
+  [Bug `1499657 <https://bugs.launchpad.net/python-openstackclient/+bug/1499657>`_]
+
+.. releasenotes/notes/bug-1656788-2f5bda2205bc0329.yaml @ b'9d946f0f45c83c5677e9dd2688830c45cb6a24af'
+
+- Fixed the ``port set`` and ``port unset`` command failures
+  (AttributeError) when ``--security-group`` option is included.
+  [Bug `1656788 <https://bugs.launchpad.net/python-openstackclient/+bug/1656788>`_]
+
+.. releasenotes/notes/bug-1658614-f84a8cece6f2ef8c.yaml @ b'e8b6a9f7be7e773396c8fe1021d8798aa0e2a4a9'
+
+- Fix wrong behavior of parsing plugin service name when the service name end
+  with keyword ``os``, like: antiddos. That cause the service api version
+  specified by users don't work.
+  [Bug `1658614 <https://bugs.launchpad.net/python-openstackclient/+bug/1658614>`_]
+
+.. releasenotes/notes/bug-1661814-1692e68a1d2d9770.yaml @ b'3afd2b7ff25af7e7998e9c8f4adac8a58a079675'
+
+- Fix ``module list --all`` command failed, and enhance the related unit
+  tests and funcational tests.
+  [Bug `1661814 <https://bugs.launchpad.net/python-openstackclient/+bug/1661814>`_]
+
+.. releasenotes/notes/bug-1663520-d880bfa51ca7b798.yaml @ b'c051c5f090fa6729a005c9d462afd8a75fc1b40f'
+
+- Fix ``server create`` command failed when ``--nic`` auto or none.
+  ``auto`` and ``none`` options was added into --nic argument of server
+  create command, but that don't work and raise internal error when execute
+  command. The patch fix that issue.
+  [Bug `1663520 <https://bugs.launchpad.net/python-openstackclient/+bug/1663520>`_]
+
+.. releasenotes/notes/bug-1665231-3df6d090d137fe4f.yaml @ b'7d93db21e59e8518ed2ca8018cecb69dc3f5b2e4'
+
+- Allow ``--default`` and ``--no-default`` options in  ``network create`` command to
+  be recognized when ``--external`` is not present.
+  [Bug `1665231 <https://bugs.launchpad.net/python-openstackclient/+bug/1665231>`_]
+
+.. releasenotes/notes/bug-1667699-6dad786b128ca8b5.yaml @ b'20429bd5c624399578cb7217e582eb86068114c6'
+
+- Fix the ``Ethertype`` column output of ``security group rule list`` command.
+  [Bug `1667699 <https://bugs.launchpad.net/python-openstackclient/+bug/1667699>`_]
+
+
+.. _python-openstackclient_3.14.3-12:
+
+3.14.3-12
+=========
+
+.. _python-openstackclient_3.14.3-12_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml @ b'defa0f562b8efc8fc917f1b195c998e2d6224260'
+
+- Add ``--name-lookup-one-by-one`` option to the ``server list`` command
+  that is (mutually exclusive with ``-n | --no-name-lookup``).
+  When provided, the names of images and flavors will be resolved one by one
+  only for those images and flavors that are needed to display the obtained
+  list of servers instead of fetching all the images and flavors.
+  Depending on amount of images in your deployment this can speed up the
+  execution of this command.
+
+.. releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml @ b'defa0f562b8efc8fc917f1b195c998e2d6224260'
+
+- When given ``--image`` or ``--flavor`` argument, the ``server list``
+  command now resolves only single image or flavor instead of fetching
+  all the images or flavors for name lookup purposes.
+
+
+.. _python-openstackclient_3.14.3-12_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1751104-compute-api-2.47-4bfa21cfaa13f408.yaml @ b'1c754197b58a28e9d30ae158560bd9921e7a8e9c'
+
+- The ``server show`` command will now properly show the server's
+  flavor information when using ``--os-compute-api-version 2.47`` or higher.
+  [Bug `1751104 <https://storyboard.openstack.org/#!/story/1751104>`_]
+
+.. releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml @ b'3228713ea302a962c11eb96ce34918b94528205e'
+
+- Re-open stdout in binary mode before writing object data in
+  ``object save --file -`` command.
+  [Bug `1775482 <https://bugs.launchpad.net/python-openstackclient/+bug/1775482>`_]
+
+.. releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml @ b'492a6c400169689182c077df5543f5ec1e481369'
+
+- The ``compute service set`` command now properly handles
+  ``--os-compute-api-version`` 2.53 and greater.
+  [Story `2005349 <https://storyboard.openstack.org/#!/story/2005349>`_]
+
+
+.. _python-openstackclient_3.14.3:
+
+3.14.3
+======
+
+.. _python-openstackclient_3.14.3_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml @ b'010da92ff3711873e40c0f5a1c262010400bf53b'
+
+- The ``openstack server add floating ip`` command has been fixed to handle
+  servers with multiple ports attached. Previously, the command was using
+  the first port in the port list when attempting to associate the floating
+  ip. This could fail if the server had multiple ports and the first port
+  in the list was not attached to an external gateway. Another way it could
+  fail is if the ``--fixed-ip-address`` option was passed and the first port
+  did not have the specified fixed IP address attached to it.
+  Now, the ``openstack server add floating ip`` command will find the port
+  attached to the specified ``--fixed-ip-address``, if provided, else it will
+  try multiple ports until one is found attached to an external gateway. If
+  a suitable port is not found in the port list, an error will be returned.
+
+
+.. _python-openstackclient_3.14.1:
+
+3.14.1
+======
+
+.. _python-openstackclient_3.14.1_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/neutron_mtu-d87e53e2d76f8612.yaml @ b'a3caf7b331709d76fc6aec5222c60688fd6112a9'
+
+- Add ``--mtu`` option to ``network create`` and ``network set``
+  commands, allowing CLI users to set the MTU for Neutron networks.
+
+
+.. _python-openstackclient_3.14.0:
+
+3.14.0
+======
+
+.. _python-openstackclient_3.14.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-device_id-to-port-list-0c658db51ce43c9e.yaml @ b'5fdd0730c88b7a3f65b728c0ea87bb34cbc1d9c4'
+
+- Add ``--device-id`` option to the ``port list`` command.
+
+.. releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml @ b'cf91d7a2f46b4a8546169a4836cc64476fce44d8'
+
+- Add support for attaching and removing qos policy to floating IPs.
+  
+  Add option ``--qos-policy`` to the ``floating ip create`` and
+  ``floating ip set`` commands to add qos policy to a floating IP.
+  
+  Add option ``--no-qos-policy`` to the ``floating ip set`` and option
+  ``--qos-policy`` to the ``floating ip unset`` command to remove the
+  qos policy from a floating IP.
+
+
+.. _python-openstackclient_3.14.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1741223-7a5c5b6e7f232628.yaml @ b'ed1b59848fd2a6b7bed7618ab5ac0db00e8110dc'
+
+- 'NoneType' object is not iterable when Glance cannot find image data in its
+  backend.
+  [Bug `1741223 <https://bugs.launchpad.net/ironic/+bug/1741223>`_]
+
+
+.. _python-openstackclient_3.13.0:
+
+3.13.0
+======
+
+.. _python-openstackclient_3.13.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-implied-role-0cdafb131fbd7453.yaml @ b'8cd3e258c5029a8efedab40019d6cfd3eac379f5'
+
+- Support for creating, deleting, and listing implied roles has been added.
+  This allows users to create an inference rule between two roles. The
+  first, called the prior role is the role explicitly assigned to an
+  individual. The second, called the implied role, is one that the user
+  is assgined implicitly.  Additionally, these rules can be chained, such
+  that an implied role from the first inference rule can be the implied role
+  in the second.  Thus one explicitly assigned role can lead to multiple
+  implied roles.
+  ``implied role create <role> --implied-role <implied-role>`` creates an
+  association between prior and implied roles.
+  ``implied role delete <role> --implied-role <implied-role>`` removes an
+  association between prior and implied roles.
+  ``implied role list`` Lists all implied roles that currently exist.
+
+.. releasenotes/notes/add-network-qos-rule-type-show-57a714a1d428726e.yaml @ b'07f0c7aa55920d65035124c9e8bfe8452356c811'
+
+- Add ``network qos rule type show`` command.
+
+.. releasenotes/notes/add-server-add-network-98ede8ff6079eb23.yaml @ b'e3ad82164dc5c51b5f3cb75b826bc15a6778b8b0'
+
+- Add ``server add network`` command. This command will create a neutron
+  port from the specified neutron network and attach the port to the
+  specified instance.
+
+.. releasenotes/notes/add-server-remove-network-fb09c53d5b0c0068.yaml @ b'809355894fac72908869739b72d44ead1c183072'
+
+- Add ``server remove network`` command. This command will remove all
+  network ports from the specified network and instance.
+
+.. releasenotes/notes/bug-1513894-6d2f05db6e1df744.yaml @ b'04ef8a41acbd45ef03253240934fa07ec170d7f4'
+
+- Add ``--use-prefix-delegation`` option to the ``subnet create`` command to
+  specify 'Prefix Delegation' as a subnetpool when creating subnets.
+  [Bug `1513894 <https://bugs.launchpad.net/bugs/1513894>`_]
+
+.. releasenotes/notes/bug-1675489-a1d226f2ee911420.yaml @ b'e7ef9e855677051383446e18e393b1f96158331b'
+
+- Add router interfaces info (as field ``interfaces_info``) to ``router show`` command. The information of router interface include port's ID, IP address, the subnet ID it belongs. [Bug `1675489 <https://bugs.launchpad.net/python-openstackclient/+bug/1675489>`_]
+
+.. releasenotes/notes/bug-1712242-934bbe2f2378f5bd.yaml @ b'82f45d9bd203aee77914c1f9e300f7dbedf673c8'
+
+- Add ``any`` as a ``--protocol`` option to ``security group rule create``
+  command.
+  [Bug `1517134 <https://bugs.launchpad.net/bugs/1712242>`_]
+
+.. releasenotes/notes/keystone-endpoint-filter-e930a7b72276fa2c.yaml @ b'12ee1861085144f43e6e535f82ba5d9b5d9a5632'
+
+- Add ``endpoint add project``, ``endpoint remove project`` and ``endpoint
+  list`` commands to manage endpoint filters in identity v3.
+
+
+.. _python-openstackclient_3.13.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1703278-5e45a92e43552dec.yaml @ b'fd23ebfbf3080b96f7ef8ba516b64e67a111971d'
+
+- Add ``--image`` and ``--password`` options to the ``server rescue`` command.
+  [Bug `1703278 <https://bugs.launchpad.net/python-openstackclient/+bug/1703278>`_]
+
+.. releasenotes/notes/bug-1711301-472b577f074edd43.yaml @ b'3a672eae7be0dcf5e2e951ea958d5d157699c341'
+
+- Fix occurrences of the ``network agent delete`` command failing with newer
+  releases of python-openstacksdk.
+  [Bug `1711301 <https://bugs.launchpad.net/python-openstackclient/+bug/1711301>`_]
+
+.. releasenotes/notes/bug-1712242-934bbe2f2378f5bd.yaml @ b'82f45d9bd203aee77914c1f9e300f7dbedf673c8'
+
+- It is now possible to create a security rule without specifying protocol
+  (using ``--protocol any``), which skips sending the protocol to the API
+  server entirely. Previously TCP was forced as default protocol when none
+  was specified.
+
+.. releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml @ b'254dbf3294c0f1edc4a2a469f556b3c4b3123a00'
+
+- Fix the ``project purge`` command to correctly delete only images owned by the
+  specified project ID when run by an administrative user.
+  [Bug `1717130 <https://bugs.launchpad.net/python-openstackclient/+bug/1717130>`_]
+
+.. releasenotes/notes/bug-1717829-c1de1d777d3abaf9.yaml @ b'de23ab8d75fe89c164b3b084c53f01c25b9040ca'
+
+- Add ``--no-fixed-ip`` option to ``port create`` command.
+  [Bug `1717829 <https://launchpad.net/bugs/1717829>`_]
+
+.. releasenotes/notes/bug-1719413-0401d05c91cc9094.yaml @ b'f6f5ce03c5b8a03180db24a02dda5b30f40b4cee'
+
+- Fix an issue with ``endpoint list`` working slow because it is issuing one GET
+  request to /v3/services/<id> Keystone API for each endpoint. In case of HTTPS
+  keystone endpoint and multiple regions it can take significant amount of time.
+  [Bug `1719413 <https://bugs.launchpad.net/python-openstackclient/+bug/1719413>`_]
+
+.. releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml @ b'4464109c7754a9287f75ec2af84398700d1450e6'
+
+- Accept ``0`` as a valid value in the ``image set`` ``--min-disk`` and ``--min-ram`` options.
+  .. _bug 1719499: https://bugs.launchpad.net/python-openstackclient/+bug/1719499
+
+.. releasenotes/notes/bug-1728525-2c40f0c19adbd0e8.yaml @ b'9ca99b991947c5b932a0c916591cd71568f2ac17'
+
+- Add ``target-all-projects`` option in ``rbac create`` command.
+  [Bug `1728525 <https://bugs.launchpad.net/python-openstackclient/+bug/1728525>`_]
+
+.. releasenotes/notes/bug-1731848-71d0a5fdb1a34a8b.yaml @ b'0f749cacc2b0a76226a6a7ab7769ecf1475a160b'
+
+- Remove the type value limit in credentials when do create,
+  reset or list. Now 'totp' method is supported in keystone
+  project and we could create credentials with 'totp' type.
+  [Bug `1731848 <https://bugs.launchpad.net/bugs/1731848>`_]
+
+.. releasenotes/notes/bug-1732216-b41bfedebff911e1.yaml @ b'116526275d0953fda93c7ff8eacd8631c5af68d5'
+
+- Fix the operation of the ``--changes-since`` option to the ``server list`` command.
+  [Bug `1732216 <https://bugs.launchpad.net/python-openstackclient/+bug/1732216>`_]
+
+.. releasenotes/notes/bug-1732938-e4d91732ef777f9a.yaml @ b'3a672eae7be0dcf5e2e951ea958d5d157699c341'
+
+- Remove the client-side check for valid ``--policy`` values in the
+  ``server group create`` command.  Specify ``--os-compute-api-version 2.15``
+  or higher for the ``soft-affinity`` or ``soft-anti-affinity`` policy.
+  [Bug `1732938 <https://bugs.launchpad.net/python-openstackclient/+bug/1732938>`_]
+
+.. releasenotes/notes/bug-1735836-9be6d777a6e6410b.yaml @ b'dab49df461d7ca68001632f11dc5bf1229271de9'
+
+- ``openstack subnet create`` failed with a NoneType exception when
+  there were no tags.
+  [Bug `1735836 <https://bugs.launchpad.net/python-openstackclient/+bug/1735836>`_]
+
+.. releasenotes/notes/support-icmp-type-code-zero-cbef0a36db2b8123.yaml @ b'221b7052abcefa56213a6516cecc6de9c73026d1'
+
+- Add support to set ``--icmp-type`` and ``--icmp-code`` to 0 in the ``security group rule`` command. [Bug `1703704 <https://bugs.launchpad.net/python-openstackclient/+bug/1703704>`_]
+
+
+.. _python-openstackclient_3.16.3-4:
+
+3.16.3-4
+========
+
+.. _python-openstackclient_3.16.3-4_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/network_dns_integration-5914b2c2be474a41.yaml @ b'e7a8687a2c87a507ce25e042014d6a918e95d035'
+
+- Add dns-domain support for network commands.
+  The new parameter ``--dns-domain`` is added to the ``network create``
+  and ``network set`` commands. This parameter sets
+  the domain name for the network.
+  Check backend available extension and return an error
+  message if it is missing (instead of a Bad Request HTTP 400).
+
+
+.. _python-openstackclient_3.16.3-4_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml @ b'47f0277208362a3224f8e587bbdd60dd5aebf846'
+
+- Re-open stdout in binary mode before writing object data in
+  ``object save --file -`` command.
+  [Bug `1775482 <https://bugs.launchpad.net/python-openstackclient/+bug/1775482>`_]
+
+
+.. _python-openstackclient_3.16.3:
+
+3.16.3
+======
+
+.. _python-openstackclient_3.16.3_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml @ b'dda007ba33b5c7d1ae539926b826749727276e3c'
+
+- Add ``--name-lookup-one-by-one`` option to the ``server list`` command
+  that is (mutually exclusive with ``-n | --no-name-lookup``).
+  When provided, the names of images and flavors will be resolved one by one
+  only for those images and flavors that are needed to display the obtained
+  list of servers instead of fetching all the images and flavors.
+  Depending on amount of images in your deployment this can speed up the
+  execution of this command.
+
+.. releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml @ b'dda007ba33b5c7d1ae539926b826749727276e3c'
+
+- When given ``--image`` or ``--flavor`` argument, the ``server list``
+  command now resolves only single image or flavor instead of fetching
+  all the images or flavors for name lookup purposes.
+
+
+.. _python-openstackclient_3.16.3_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml @ b'bb7f49168563414d65b4050e84a8d1d4915206bc'
+
+- Fix ``endpoint group delete`` command to properly delete endpoint groups.
+  [Story `2005521 <https://storyboard.openstack.org/#!/story/2005521>`_]
+
+.. releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml @ b'fc5f2978c0f4f1e3360325b00c1f1b99f1e6318f'
+
+- The ``compute service set`` command now properly handles
+  ``--os-compute-api-version`` 2.53 and greater.
+  [Story `2005349 <https://storyboard.openstack.org/#!/story/2005349>`_]
+
+
+.. _python-openstackclient_3.16.2:
+
+3.16.2
+======
+
+.. _python-openstackclient_3.16.2_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml @ b'e09c358e7b35ac938595aad90c5c42dfe402a42a'
+
+- The ``openstack server add floating ip`` command has been fixed to handle
+  servers with multiple ports attached. Previously, the command was using
+  the first port in the port list when attempting to associate the floating
+  ip. This could fail if the server had multiple ports and the first port
+  in the list was not attached to an external gateway. Another way it could
+  fail is if the ``--fixed-ip-address`` option was passed and the first port
+  did not have the specified fixed IP address attached to it.
+  Now, the ``openstack server add floating ip`` command will find the port
+  attached to the specified ``--fixed-ip-address``, if provided, else it will
+  try multiple ports until one is found attached to an external gateway. If
+  a suitable port is not found in the port list, an error will be returned.
+
+
+.. _python-openstackclient_3.16.0:
+
+3.16.0
+======
+
+.. _python-openstackclient_3.16.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add ``image member list`` command to list all members of an image.
+
+.. releasenotes/notes/add-image-tag-filter-support-5cb039416b07caab.yaml @ b'9edbab8c90bb74ba12892d0c77c8e8a99d4868fe'
+
+- Add ``--tag`` option to ``image list`` command to filter by tag.
+
+.. releasenotes/notes/add-server-create-image-property-ef76af26233b472b.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add  ``--image-property`` option to ``server create`` command.
+  This parameter will filter a image which properties that are matching.
+
+.. releasenotes/notes/allow-port-list-with-ip-address-substr-14c5805b241e402f.yaml @ b'4a9cb8eea8e47950cb30ecaa7572a23d80d5bfcd'
+
+- Add an ``ip-substring`` key to the ``--fixed-ip`` option of the
+  ``port list`` command.  This allows filtering ports by a substring
+  match of an IP address.
+  [Bug `1718605 <https://bugs.launchpad.net/bugs/1718605>`_]
+
+.. releasenotes/notes/bp-unified-limits-58f166401534a4ff.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add ``registered limit`` commands for managing registered limits in Keystone.
+  Registered limits define limits of resources for projects to assume by default.
+  [`bp unified-limits <https://blueprints.launchpad.net/keystone/+spec/unified-limit>`_]
+
+.. releasenotes/notes/bp-unified-limits-6c5fdb1c26805d86.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add ``limit`` commands for managing project-specific limits in keystone.
+  Limits define limits of resources for projects to consume once a limit
+  has been registered.
+  [`bp unified-limits <https://blueprints.launchpad.net/keystone/+spec/unified-limit>`_]
+
+.. releasenotes/notes/bug-1750983-420945d6c0afb509.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add ``--tag`` and ``--no-tag`` options to ``security group create`` and
+  ``security group set`` commands.
+  [Bug `1750983 <https://bugs.launchpad.net/python-openstackclient/+bug/1750983>`_]
+
+.. releasenotes/notes/bug-1750983-420945d6c0afb509.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add ``--tags``, ``--any-tags``, ``--not-tags`` and ``--not-any-tags`` options
+  to ``security group list`` command.
+  [Bug `1750983 <https://bugs.launchpad.net/python-openstackclient/+bug/1750983>`_]
+
+.. releasenotes/notes/bug-1750983-420945d6c0afb509.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add ``--tag`` and ``--all-tag`` options to ``security group unset`` command.
+  [Bug `1750983 <https://bugs.launchpad.net/python-openstackclient/+bug/1750983>`_]
+
+.. releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml @ b'7e8c55fa1bbc5f44b9233602786c22d6019eef22'
+
+- Add ``--description`` option to ``flavor set`` command to update the description of the flavor. Only available starting with ``--os-compute-api-version 2.55``.
+
+.. releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml @ b'7e8c55fa1bbc5f44b9233602786c22d6019eef22'
+
+- Add ``--description`` option to ``flavor create`` command to set the description of the flavor. Only available starting with ``--os-compute-api-version 2.55``.
+
+.. releasenotes/notes/implement-system-scope-4c3c47996f98deac.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- Add support for system-scope to ``role`` commands. This includes the ability to
+  generate system-scoped tokens using ``system_scope: all`` in ``cloud.yaml``
+  or ``OS_SYSTEM_SCOPE=all`` in an environment variable. Support is also
+  included for managing role assignments on the system using ``--system``
+  when adding and removing roles.
+  [`bp system-scope <https://blueprints.launchpad.net/keystone/+spec/system-scope>`_]
+
+.. releasenotes/notes/subnet-set-segment-id-4440e433b170f9f3.yaml @ b'e8c731547d85b1241c7898d2fb77b8d635901dfd'
+
+- Add ``--network-segment`` option to ``subnet set`` command. This enables the possiblity to set the ``segment_id`` of a subnet on update.
+
+.. releasenotes/notes/versions-show-12a2443624c83048.yaml @ b'9ece632f96844fd78c2f717f2f6d35e61c3b9ef2'
+
+- A new command, ``openstack versions show`` was added, which will
+  provide a list of all versions of all services in the cloud. It
+  includes relevant metadata, such as min/max microversion, endpoint,
+  status and region.
+
+
+.. _python-openstackclient_3.16.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/add-community-option-to-image-list-ac0651eb2e5d632f.yaml @ b'860639a548a2c07193662cd361432cb5061c2a7f'
+
+- Add ``--community`` option to ``image list`` command. [Bug `2001925 <https://storyboard.openstack.org/#!/story/2001925>`_]
+
+.. releasenotes/notes/bug-1742453-ae4be6de90a3ae1d.yaml @ b'c615bcd75e85a2a2231d9944caeffd746e881e5e'
+
+- The ``server list --all`` command now resolves non-public flavor names,
+  too, so that the ``Flavor`` column will be properly populated.
+  [Bug `1742453 <https://bugs.launchpad.net/bugs/1742453>`_]
+
+.. releasenotes/notes/bug-1750985-a5345f715a14825c.yaml @ b'09a0916daeeb9c257d84175a43062d5b4a1d0b1a'
+
+- Add ``--tag`` support to ``floating ip create|list|set|unset`` commands.
+  [:lpbug:`1750985`]
+
+.. releasenotes/notes/bug-1751104-compute-api-2.47-4bfa21cfaa13f408.yaml @ b'4236d777ffb6f03bb2682142aaa18b48e9a00d96'
+
+- The ``server show`` command will now properly show the server's
+  flavor information when using ``--os-compute-api-version 2.47`` or higher.
+  [Bug `1751104 <https://storyboard.openstack.org/#!/story/1751104>`_]
+
+
+.. _python-openstackclient_3.16.0_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/remove-ip-floating-commands-d5363f313e09249a.yaml @ b'ea89065dabf92c2684e55c4b37c7be9b667cfa1e'
+
+- Remove deprecated ``ip floating`` and ``ip floating pool`` commands.
+
+
+.. _python-openstackclient_3.15.0:
+
+3.15.0
+======
+
+.. _python-openstackclient_3.15.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/bp-application-credential-a7031a043efc4a25.yaml @ b'375964f270e125b8887e0ca4ee1cbe15d5eddf04'
+
+- Adds support for creating, reading, and deleting application credentials
+  via the ``appication credential`` command. With application credentials, a
+  user can grant their applications limited access to their cloud resources.
+  Once created, users can authenticate with an application credential by
+  using the ``v3applicationcredential`` auth type.
+  [`blueprint application-credentials <https://blueprints.launchpad.net/keystone/+spec/application-credentials>`_]
+
+.. releasenotes/notes/bp-project-tags-b544aef9672d415b.yaml @ b'd32664150fbc00340f3ff4304c13abf9a191299a'
+
+- Add ``--tag`` option to ``project create`` command,  ``--tag``, ``--clear-tags``, and
+  ``--remove-tag`` options to ``project set`` command. Add ``--tags``, ``--tags-any``, 
+  ``--not-tags``, and ``--not-tags-any`` options to ``project list`` command to filter
+  list results by different projects based on their tags.
+  [`blueprint project-tags <https://blueprints.launchpad.net/keystone/+spec/project-tags>`_]
+
+.. releasenotes/notes/bug-1714878-46806jv2yv13q054.yaml @ b'4a9e84be994575146b30bd40a341d5686174eaad'
+
+- Add ``--dns-domain`` option to ``port create`` and ``port set`` commands.
+  Requires the ``dns_domain for ports`` extension to be enabled. See the
+  `Neutron DNS integration <https://docs.openstack.org/neutron/latest/admin/config-dns-int.html>`_
+  documentation for information how to use this.
+  [Bug `1714878 <https://bugs.launchpad.net/python-openstackclient/+bug/1714878>`_]
+
+.. releasenotes/notes/keystone-endpoint-group-0c55debbb66844f2.yaml @ b'1eae301c4fab30c551ed7542cdaf8735cbbc3822'
+
+- Add endpoint group commands: ``endpoint group add project``, ``endpoint group create``,
+  ``endpoint group delete``, ``endpoint group list``, ``endpoint group remove project``,
+  ``endpoint group set`` and ``endpoint group show``.
+  [Blueprint `keystone-endpoint-filter <https://blueprints.launchpad.net/python-openstackclient/+spec/keystone-endpoint-filter>`_]
+
+.. releasenotes/notes/neutron_mtu-d87e53e2d76f8612.yaml @ b'18563b4132f794cc6612c2897795f96a31b565ae'
+
+- Add ``--mtu`` option to ``network create`` and ``network set``
+  commands, allowing CLI users to set the MTU for Neutron networks.
+
+
+.. _python-openstackclient_3.18.1-3:
+
+3.18.1-3
+========
+
+.. _python-openstackclient_3.18.1-3_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml @ b'29ec8c8134072b9b3eb6ff89320506bef9ec358a'
+
+- Re-open stdout in binary mode before writing object data in
+  ``object save --file -`` command.
+  [Bug `1775482 <https://bugs.launchpad.net/python-openstackclient/+bug/1775482>`_]
+
+.. releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml @ b'3b48ef54c8ad205dd086520cc17e4f96583e88ec'
+
+- Fixes the "No server with a name or ID of 'id' exists" error when running
+  ``server list --deleted --marker``. The fix removes using a name for
+  the marker when both ``--deleted`` and ``--marker`` are used. In
+  this scenario an ID must be supplied for the marker.
+  [Story `2006761 <https://storyboard.openstack.org/#!/story/2006761>`_]
+
+
+.. _python-openstackclient_3.18.1:
+
+3.18.1
+======
+
+.. _python-openstackclient_3.18.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml @ b'fd3a94d16be8e7806ff4f3aa7417d8a0d36375fb'
+
+- Fix ``endpoint group delete`` command to properly delete endpoint groups.
+  [Story `2005521 <https://storyboard.openstack.org/#!/story/2005521>`_]
+
+.. releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml @ b'100d34c54ecdfedf6fb40a2686e1aae1f54df97e'
+
+- The ``compute service set`` command now properly handles
+  ``--os-compute-api-version`` 2.53 and greater.
+  [Story `2005349 <https://storyboard.openstack.org/#!/story/2005349>`_]
+
+
+.. _python-openstackclient_3.18.0:
+
+3.18.0
+======
+
+.. _python-openstackclient_3.18.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-member-status-filter-2e118b2c93151223.yaml @ b'444a40c656b9f6007364ecd3bcf38964bbcd4556'
+
+- Add ``--member-status`` option to ``image list`` command.
+
+.. releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml @ b'239b103849b96213dc9cb317006346ce311228e4'
+
+- From microversion 2.69 the results of ``openstack server list`` and
+  ``openstack server show`` may contain missing information in their outputs
+  when there are partial infrastructure failure periods in the deployment.
+  See `Handling Down Cells`_ for more information on the missing keys/info.
+  
+  .. _Handling Down Cells: https://developer.openstack.org/api-guide/compute/down_cells.html
+
+.. releasenotes/notes/bp-network-segment-range-management-0abf03fe03eea149.yaml @ b'd52920b3878479f7dd549cba1679870b4f00ee33'
+
+- Add ``network segment range create``, ``network segment range delete``, ``network segment range list``, ``network segment range show`` and ``network segment range set`` commands. [Blueprint `network-segment-range-management <https://blueprints.launchpad.net/neutron/+spec/network-segment-range-management>`_]
+
+.. releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml @ b'e776a4f0260af1d2ae66439e647794395d470578'
+
+- Add ``--attached`` and ``--detached`` options to ``volume set`` command to set the
+  volume status in the database.  This is the functional equivalent to
+  ``cinder reset-state --attach-status``.
+  [`bug 1745699 <https://bugs.launchpad.net/python-openstackclient/+bug/1745699>`_
+
+.. releasenotes/notes/floatingip_dns_integration-f26c7575694d098d.yaml @ b'ed09f28a9dd1cbc0f8c141a8e38587b7022d4166'
+
+- Add ``--dns-domain`` and ``--dns-name`` options to the 
+  ``floating ip create`` commands. These options
+  set the DNS domain and name for the floating IP.
+  
+  Check backend available extension and return an error
+  message if it is missing (instead of a Bad Request HTTP 400).
+  [Bug `1547736 <https://storyboard.openstack.org/#!/story/1547736>`_]
+
+.. releasenotes/notes/floatingip_dns_integration-f26c7575694d098d.yaml @ b'ed09f28a9dd1cbc0f8c141a8e38587b7022d4166'
+
+- Add ``--long`` option to the ``floating ip list`` command.  This adds
+  ``DNS Name`` and ``DNS Domain`` columns to the floating IP list.
+  [Bug `1547736 <https://storyboard.openstack.org/#!/story/1547736>`_]
+
+.. releasenotes/notes/image-list-filter-multiple-properties-03c51d43131ee3b6.yaml @ b'21e4c87bdeb78ef5c5a251ae9e671efd1b5e3102'
+
+- The ``image list`` command now properly filters images on multiple
+  ``--property`` options.
+  [Bug `2004290 <https://storyboard.openstack.org/#!/story/2004290>`_]
+
+.. releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml @ b'75cba9d1cbdd7b14b0d507af27f896c6c45e713e'
+
+- Add support for list detailed ``quota`` usage for project.
+  This can be done by passing ``--detail`` parameter to `quota list` command.
+  [Bug `1716043 <https://bugs.launchpad.net/neutron/+bug/1716043>`_]
+
+.. releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml @ b'e782f49927a6b142a35f85a1a4a759fd2b1ceedf'
+
+- Add ``--name-lookup-one-by-one`` option to the ``server list`` command
+  that is (mutually exclusive with ``-n | --no-name-lookup``).
+  When provided, the names of images and flavors will be resolved one by one
+  only for those images and flavors that are needed to display the obtained
+  list of servers instead of fetching all the images and flavors.
+  Depending on amount of images in your deployment this can speed up the
+  execution of this command.
+
+.. releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml @ b'e782f49927a6b142a35f85a1a4a759fd2b1ceedf'
+
+- When given ``--image`` or ``--flavor`` argument, the ``server list``
+  command now resolves only single image or flavor instead of fetching
+  all the images or flavors for name lookup purposes.
+
+.. releasenotes/notes/network_dns_integration-5914b2c2be474a41.yaml @ b'b8754e15e7adc9a04587f67c83febaf49b64f18c'
+
+- Add dns-domain support for network commands.
+  The new parameter ``--dns-domain`` is added to the ``network create``
+  and ``network set`` commands. This parameter sets
+  the domain name for the network.
+  Check backend available extension and return an error
+  message if it is missing (instead of a Bad Request HTTP 400).
+
+.. releasenotes/notes/osc-included-image-signing-a7021a4dbdcf6336.yaml @ b'1981eb22500b7c389befc8e91d7ba5cebbe19a88'
+
+- Add options ``--sign-key-path`` and ``--sign-cert-id`` to the ``image create``
+  command.  Tthe image must be present on disk, therefore the ``file`` option
+  is required:
+  
+  ``image create --file <filename> --sign-key-path <key-path> --sign-cert-id <secret-id>``.
+  
+  A prompt for a password ensures, that the private key can be protected too.
+  [Bug `2002128 <https://storyboard.openstack.org/#!/story/2002128>`_]
+
+.. releasenotes/notes/router-gateway-IP-QoS-c8ba95e180bca05f.yaml @ b'fd23025227a07e879e0b29c67063401b1d392518'
+
+- Add support for attaching and removing qos policy to router gateway IPs.
+  
+  Add ``--qos-policy`` and ``--no-qos-policy`` options to the
+  ``router set`` command.
+  
+  Add ``--qos-policy`` option to the ``router unset`` command.
+
+.. releasenotes/notes/server-rebuild-property-e8c6439b04e27c80.yaml @ b'e3dc30fe8c1ae6a13926bf1eae52097e8bb37aab'
+
+- Add ``--property`` option to the ``server rebuild`` command, to provide
+  the ability to specify properties of the rebuilt instance.
+  [Story `2003979 <https://storyboard.openstack.org/#!/story/2003979>`_]
+
+.. releasenotes/notes/server-rebuild-with-keypair-name-83c1aa20db136d91.yaml @ b'f82c5b85ce9d6fee62550044fbabe54155e4b367'
+
+- Add ``--key-name`` option to ``server rebuild`` command to set keypair of the server. Note that it requires --os-compute-api-version 2.54 or later.
+
+.. releasenotes/notes/server-rebuild-with-keypair-name-83c1aa20db136d91.yaml @ b'f82c5b85ce9d6fee62550044fbabe54155e4b367'
+
+- Add ``--key-unset`` option to ``server rebuild`` command to unset keypair. Note that it requires --os-compute-api-version 2.54 or later.
+
+.. releasenotes/notes/support-uplink_status_propagation-4d37452bcf03e0f8.yaml @ b'c82f4237e59dd61f180b2bfbd3383c6540cd6cef'
+
+- Add ``--enable-uplink-status-propagation`` option and
+  ``--disable-uplink-status-propagation`` option to ``port create`` command.
+
+.. releasenotes/notes/volume-backend-c5faae0b31556a24.yaml @ b'e0615e8d69152ce0417f873b30050802a2da0da8'
+
+- Add ``openstack volume backend capability show <host>`` command that
+  provides a list of all capabilities that can be configured
+  for the requested backend. The required `<host>` parameter takes the form
+  `host@backend-name`.
+
+.. releasenotes/notes/volume-backend-c5faae0b31556a24.yaml @ b'e0615e8d69152ce0417f873b30050802a2da0da8'
+
+- Add ``openstack volume backend pool list`` command that provides
+  a list of all backend storage pools. The optional ``--long``
+  parameter includes some basic configuration and stats for each pool.
+
+
+.. _python-openstackclient_3.18.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/unlock-volume-a6990fc3bf1f5f67.yaml @ b'f00ffebea61f94f2334d1c1578bc23986bbcf58c'
+
+- The ``volume migrate --unlock`` argument did not actually do anything and
+  has now been removed.
+
+
+.. _python-openstackclient_3.18.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/bug-1777153-750e6044aa28d5d8.yaml @ b'030fd71390e8e4b8413e916e64076337035f9aa7'
+
+- The ``--project`` and ``--user`` options for the ``volume create``
+  command have been deprecated. They are deprecated because Cinder's
+  volume create API ignores the corresponding API inputs.
+
+
+.. _python-openstackclient_3.18.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1777153-750e6044aa28d5d8.yaml @ b'030fd71390e8e4b8413e916e64076337035f9aa7'
+
+- Fix ``volume create`` by removing two broken options. The ``--project``
+  and ``--user`` options were intended to specify an alternate project
+  and/or user for the volume, but the Volume service's API does not
+  support this behavior. This caused the volume to be created, but
+  without the expected project/user values. However, an alternate
+  project and/or user may be specified using identity overrides (e.g.
+  --os-username, --os-project-id).
+
+.. releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml @ b'013c9a4f3a44cb0b81fc7affe9b933e701cb5dba'
+
+- The ``openstack server add floating ip`` command has been fixed to handle
+  servers with multiple ports attached. Previously, the command was using
+  the first port in the port list when attempting to associate the floating
+  ip. This could fail if the server had multiple ports and the first port
+  in the list was not attached to an external gateway. Another way it could
+  fail is if the ``--fixed-ip-address`` option was passed and the first port
+  did not have the specified fixed IP address attached to it.
+  Now, the ``openstack server add floating ip`` command will find the port
+  attached to the specified ``--fixed-ip-address``, if provided, else it will
+  try multiple ports until one is found attached to an external gateway. If
+  a suitable port is not found in the port list, an error will be returned.
+
+
+.. _python-openstackclient_4.0.2-9:
+
+4.0.2-9
+=======
+
+.. _python-openstackclient_4.0.2-9_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml @ b'a36ac0596cddabadc2154b9c7600abe2a2064b91'
+
+- Add ``--limit`` and ``--offset`` options to ``server group list`` command,
+  to configure pagination of results.
+
+.. releasenotes/notes/add-parent-list-option-to-projects-10382a7176993366.yaml @ b'03c28595d172abecf0ae89b38447c67bcedc92b4'
+
+- Add ``--parent`` option to ``project list`` command to filter projects
+  by the specified parent project.
+
+.. releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml @ b'63e15ff405c46821d64676900edf020973c280de'
+
+- Add support for compute API microversion 2.47, which changes how flavor
+  details are included in server detail responses. In 2.46 and below,
+  only the flavor ID was shown in the server detail response. Starting in
+  2.47, flavor information is embedded in the server response. The newer
+  behavior is now supported.
+
+
+.. _python-openstackclient_4.0.2-9_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml @ b'b948e74b88befca67eab57573444e81f44eb75c9'
+
+- Remove deprecated neutron-lbaas results from ``quota show`` command.
+
+
+.. _python-openstackclient_4.0.2:
+
+4.0.2
+=====
+
+.. _python-openstackclient_4.0.2_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml @ b'2e0a0f15cf50e200925aebd9659d903c79b5b68e'
+
+- You can now remove role assignments from keystone that reference non-existent
+  users or groups.
+  
+  [Bug `2006635 <https://storyboard.openstack.org/#!/story/2006635>`_]
+
+
+.. _python-openstackclient_4.0.1:
+
+4.0.1
+=====
+
+.. _python-openstackclient_4.0.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml @ b'bff556c7c2e19d6162fb47929b91c155eba2a6ee'
+
+- [Story `2005246 <https://storyboard.openstack.org/#!/story/2005246>`_]
+  The `is_domain` property safely handles type checking.
+
+.. releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml @ b'c42c27aa926e93a2507e686eeaf0c5510a29d245'
+
+- Fixes the "No server with a name or ID of 'id' exists" error when running
+  ``server list --deleted --marker``. The fix removes using a name for
+  the marker when both ``--deleted`` and ``--marker`` are used. In
+  this scenario an ID must be supplied for the marker.
+  [Story `2006761 <https://storyboard.openstack.org/#!/story/2006761>`_]
+
+
+.. _python-openstackclient_4.0.0:
+
+4.0.0
+=====
+
+.. _python-openstackclient_4.0.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-fip-portforwarding-commands-6e4d8ace698ee308.yaml @ b'f044016e296fd261f61eda69fb2f5ef87de6e0a9'
+
+- Add floating IP Port Forwarding commands:
+  ``floating ip port forwarding create``,
+  ``floating ip port forwarding delete``,
+  ``floating ip port forwarding list``,
+  ``floating ip port forwarding set`` and
+  ``floating ip port forwarding show``.
+
+.. releasenotes/notes/add-host-and-hypervisor-hostname-flag-to-create-server-cb8b39a9f9311d42.yaml @ b'340f25fa14d42205a4134ce4cba47792764b8542'
+
+- Add ``--host`` and ``--hypervisor-hostname`` options to
+  ``server create`` command.
+  [Blueprint `add-host-and-hypervisor-hostname-flag-to-create-server <https://blueprints.launchpad.net/nova/+spec/add-host-and-hypervisor-hostname-flag-to-create-server>`_]
+
+.. releasenotes/notes/add-server-migrate-with-host-4884a71903c5c8a9.yaml @ b'cb0c20b23c564dc6b260492923aef58ee66620d9'
+
+- Add ``--host`` option to ``server migrate`` command
+  (cold migration) to specify the target host of the migration.
+  Requires ``--os-compute-api-version`` 2.56 or greater to target a
+  specific host for the (cold) migration.
+  [Story `2003325 <https://storyboard.openstack.org/#!/story/2003325>`_]
+
+.. releasenotes/notes/add-server-resize-confirm-revert-commands-98854ca98965432a.yaml @ b'7561e062ebd80a28655523320cbe1a49e94ee509'
+
+- Add ``server resize confirm`` and ``server resize revert`` commands.
+  These replace the now deprecated ``--confirm`` and ``--revert``
+  options to the ``server resize`` commands, respectively.
+
+.. releasenotes/notes/allow-port-create-with-extra-dhcp-options-c2c40e4002b52e2a.yaml @ b'68809fce5a1073659001a87aee4f9407affd5d0e'
+
+- Add ``--extra-dhcp-options`` parameter to the ``port create`` command. The
+  neutronclient ``port-create`` command can accept extra DHCP options, add
+  it to the openstackclient in order to be consistent.
+
+.. releasenotes/notes/better-ipv6-address-suppport-security-group-rules-95272847349982e5.yaml @ b'cb0c20b23c564dc6b260492923aef58ee66620d9'
+
+- Add ``--ethertype`` option to ``security group rule list`` command.
+  Valid values are ``ipv4`` and ``ipv6``.
+
+.. releasenotes/notes/bp-add-locked-reason-425efd2def1144f1.yaml @ b'187be0ac22be5d2d1c42d45e9299e62cfc3796ae'
+
+- Add ``--reason`` option to the ``server lock`` command to specify a reason when locking a server. Requires ``–os-compute-api-version`` 2.73 or greater.
+
+.. releasenotes/notes/bp-add-locked-reason-425efd2def1144f1.yaml @ b'187be0ac22be5d2d1c42d45e9299e62cfc3796ae'
+
+- Add ``--locked`` option to the ``server list`` command to list only locked servers. Requires ``–os-compute-api-version`` 2.73 or greater.
+
+.. releasenotes/notes/bp-add-locked-reason-425efd2def1144f1.yaml @ b'187be0ac22be5d2d1c42d45e9299e62cfc3796ae'
+
+- Add ``--unlocked`` option to the ``server list`` command list only unlocked servers. Requires ``–os-compute-api-version`` 2.73 or greater. [Blueprint `add-locked-reason <https://blueprints.launchpad.net/nova/+spec/add-locked-reason>`_]
+
+.. releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-16e864223d51b50a.yaml @ b'dd1ce370424264166be686578bcab0fa41ac973e'
+
+- Add ``--availability-zone`` option to ``server unshelve`` command to enable users to specify an availability zone during unshelve of a shelved offloaded server. Note that it requires ``--os-compute-api-version 2.77`` or greater. [Blueprint `support-specifying-az-when-restore-shelved-server <https://blueprints.launchpad.net/nova/+spec/support-specifying-az-when-restore-shelved-server>`_]
+
+.. releasenotes/notes/story-2006302-add-boot-from-volume-cd411b1ca776bb3c.yaml @ b'b9d63105566c84db11a976846844ad7b3a0b331e'
+
+- Add ``--boot-from-volume`` option to the ``server create`` command
+  to create a volume-backed server from the specified image with the
+  specified size when used in conjunction with the ``--image`` or
+  ``--image-property`` options.
+  [Story `2006302 <https://storyboard.openstack.org/#!/story/2006302>`_]
+
+.. releasenotes/notes/story-2006302-support-bdm-type-image-0becfb63bd4fb969.yaml @ b'6a199bd14152889f18ad95919a4bee9c0c083d5d'
+
+- The ``server create --block-device-mapping`` option now supports
+  an ``image`` type in addition to ``volume`` and ``snapshot``. When
+  specifying an image block device the compute service will create a volume
+  from the image of the specified size and attach it to the server.
+  [Story `2006302 <https://storyboard.openstack.org/#!/story/2006302>`_]
+
+
+.. _python-openstackclient_4.0.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/better-ipv6-address-suppport-security-group-rules-95272847349982e5.yaml @ b'cb0c20b23c564dc6b260492923aef58ee66620d9'
+
+- Security group rule listings now have the ``Ethertype`` field displayed
+  by default to more easily differentiate between IPv4 and IPv6 rules.
+  In addition, the ``IP Range`` field of a security group will be
+  changed to ``0.0.0.0/0`` for IPv4 and ``::/0`` for IPv6 if no
+  value is returned for the address, based on the Ethertype field of
+  the rule. For further information see
+  [Bug `1735575 <https://bugs.launchpad.net/bugs/1735575>`_]
+
+.. releasenotes/notes/bug-1716789-abfae897b7e61246.yaml @ b'cb0c20b23c564dc6b260492923aef58ee66620d9'
+
+- Commands that assumed the default value of ``--protocol`` to be ``tcp``
+  now must include ``--protocol tcp`` explicitly in Network commands.
+
+.. releasenotes/notes/osc4-compute-09246008eff260cb.yaml @ b'b7742b59371b9e0b2e417547eb2cdaa80954b50d'
+
+- Remove deprecated ``ip fixed add|remove`` commands.
+  Use ``server add|remove fixed ip`` commands instead.
+
+.. releasenotes/notes/osc4-compute-09246008eff260cb.yaml @ b'b7742b59371b9e0b2e417547eb2cdaa80954b50d'
+
+- Remove deprecated ``ip floating add|remove`` commands.
+  Use ``server add|remove floating ip`` commands instead.
+
+.. releasenotes/notes/osc4-identity-6564257c67d43106.yaml @ b'f9fdc296bc6f2c1f7d6196352b754a7617c4f2d2'
+
+- Remove deprecated ``role list`` options ``--project`` and ``--user``.
+  Use ``role assignment list`` options ``--project`` and ``--user`` instead.
+
+.. releasenotes/notes/osc4-identity-6564257c67d43106.yaml @ b'f9fdc296bc6f2c1f7d6196352b754a7617c4f2d2'
+
+- Remove deprecated ``user role list`` command.
+  Use ``role assignment list`` options ``--project`` and ``--user`` instead.
+
+.. releasenotes/notes/osc4-identity-6564257c67d43106.yaml @ b'f9fdc296bc6f2c1f7d6196352b754a7617c4f2d2'
+
+- Remove deprecated ``service create`` option ``--type``.  
+  The type is supplied as a positional argument in The
+  ``service create --name <service-name> type`` command.
+
+.. releasenotes/notes/osc4-image-e922ee6f8e028648.yaml @ b'67dadda746759d8cf47822e6f426c473e46acc27'
+
+- Remove ``image create|set`` option ``--owner``.
+  Use ``--project`` option instead.
+
+.. releasenotes/notes/osc4-network-db2aed696d964ca6.yaml @ b'5a0fc68a87d1c9733c1dd5bb6f68b2e518fe2105'
+
+- Remove deprecated ``port create|set`` options ``--device-id`` and ``--host-id``.
+  Use ``--device`` and ``--host`` options instead.
+
+.. releasenotes/notes/osc4-network-db2aed696d964ca6.yaml @ b'5a0fc68a87d1c9733c1dd5bb6f68b2e518fe2105'
+
+- Remove deprecated ``router set`` option ``--clear-routes``.
+  Use ``--no-route`` option instead.
+
+.. releasenotes/notes/osc4-network-db2aed696d964ca6.yaml @ b'5a0fc68a87d1c9733c1dd5bb6f68b2e518fe2105'
+
+- Remove deprecated ``security group rule create`` options ``--src-ip`` and
+  ``--src-group``.
+  Use ``--remote-ip`` and ``--remote-group`` options instead.
+
+.. releasenotes/notes/osc4-volume-470422e5a453310e.yaml @ b'e76e10c0bac9cf87c564a7f0201df189f7cd8b52'
+
+- Remove deprecated ``backup`` commands.
+  Use ``volume backup`` commands instead.
+
+.. releasenotes/notes/osc4-volume-470422e5a453310e.yaml @ b'e76e10c0bac9cf87c564a7f0201df189f7cd8b52'
+
+- Remove deprecated ``snapshot`` commands.
+  Use ``volume snapshot`` commands instead.
+
+.. releasenotes/notes/osc4-volume-470422e5a453310e.yaml @ b'e76e10c0bac9cf87c564a7f0201df189f7cd8b52'
+
+- Remove deprecated ``volume create`` options ``--project``, ``--user``
+  and ``--multi-attach``.
+
+.. releasenotes/notes/osc4-volume-470422e5a453310e.yaml @ b'e76e10c0bac9cf87c564a7f0201df189f7cd8b52'
+
+- Change ``volume transfer request accept`` to use new required option
+  ``--auth-key`` rather than a second positional argument.
+
+.. releasenotes/notes/volume-v3-default-0ffa9bebb43b5057.yaml @ b'cb0c20b23c564dc6b260492923aef58ee66620d9'
+
+- Volume commands now default to Volume API 3.  On older clouds
+  that do not support Volume 3.x ``--os-volume-api-version 2``
+  or the adition of ``volume_api_version: '2'`` in ``clouds.yaml``
+  will be required.
+
+
+.. _python-openstackclient_4.0.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/add-server-resize-confirm-revert-commands-98854ca98965432a.yaml @ b'7561e062ebd80a28655523320cbe1a49e94ee509'
+
+- Deprecate the ``--confirm`` and ``--revert`` options for the
+  ``server resize`` command. They have been replaced with the
+  ``server resize confirm`` and `server resize revert`` commands,
+  respectively.
+
+
+.. _python-openstackclient_4.0.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1716789-abfae897b7e61246.yaml @ b'cb0c20b23c564dc6b260492923aef58ee66620d9'
+
+- Change the default value of ``--protocol`` option to ``any`` in
+  ``security group rule create`` command when using the Neutron v2 API.
+  [Bug `1716789 <https://bugs.launchpad.net/bugs/1716789>`_]
+
+.. releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml @ b'4bd53dc1090fda86f6ce25b76a079e250c9206d8'
+
+- The ``compute service set`` command now properly handles
+  ``--os-compute-api-version`` 2.53 and greater.
+  [Story `2005349 <https://storyboard.openstack.org/#!/story/2005349>`_]
+
+.. releasenotes/notes/usage-list-all-49ca7a62c50e71d3.yaml @ b'037a800538feb690af0541d4f276dcdf48af3f72'
+
+- Compute API v2.40+ returns all matching entities rather than being
+  limited to the API server configured maximum (``CONF.api.max_limit``).
+  [Story `2005099 <https://storyboard.openstack.org/#!/story/2005099>`_]
+
+
+.. _python-openstackclient_4.0.0_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/config-show-00512dc60882e5c0.yaml @ b'865e182970c9ce42d5be07cd3b81fb5dd1a3e656'
+
+- The ``configuration show`` command no longer requires authentication.
+  This is useful in debugging cloud configurations, particularly
+  auth configurations.
+
+
+.. _python-openstackclient_3.19.0:
+
+3.19.0
+======
+
+.. _python-openstackclient_3.19.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/bug-1827844-8f1de120087c6a22.yaml @ b'ef1fd388154eee11b9e83f80e5004670fdffb6cc'
+
+- Add ``--changes-before`` option to the ``server list`` command.
+  This requires Compute API version '2.66' or later.
+  [:lpbug: `1827844`]
+
+.. releasenotes/notes/rbac-add-security-group-35370701a06ac906.yaml @ b'be7a75814ca4a503dd384f36166f93f12f6cb8da'
+
+- Add ``security_group`` as a valid ``--type`` value for the
+  ``network rbac create`` and ``network rbac list`` commands.
+
+.. releasenotes/notes/server-description-ae9618fc09544cac.yaml @ b'c77a9621beaf7748e5ccfecb3ac37fa9602c5bfe'
+
+- Add ``--description`` option to ``server create``, ``server rebuild``,
+  ``server set`` and ``server unset`` commands.
+  [Bug `2002005 <https://storyboard.openstack.org/#!/story/2002005>`_]
+
+
+.. _python-openstackclient_3.19.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/bug-1411190-live-migration-host-655ae6befa6a3de2.yaml @ b'3057989714e5e510e275c454258e0f167ed551d2'
+
+- The ``--live`` option on the ``openstack server migrate`` command has
+  been deprecated and is being replaced with two new options:
+  
+  * ``--live-migration``: This will signal that the migration is a live
+    migration.
+  * ``--host``: This can be used to request a target host for the live
+    migration but requires ``--os-compute-api-version`` 2.30 or greater
+    so the requested host can be validated by the scheduler.
+  
+  The ``--live`` option is problematic in that it requires a host and
+  prior to compute API version 2.30, specifying a host during live migration
+  will bypass validation by the scheduler which could result in failures to
+  actually migrate the server to the specified host or over-subscribe the
+  host.
+  
+  The ``--live`` and ``--host`` options are mutually exclusive. Furthermore,
+  if both the ``--live`` and ``--live-migration`` options are used the
+  ``--live-migration`` option takes priority.
+
+
+.. _python-openstackclient_3.19.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1411190-live-migration-host-655ae6befa6a3de2.yaml @ b'3057989714e5e510e275c454258e0f167ed551d2'
+
+- `Bug 1411190`_ has been fixed by providing a ``--live-migration`` and
+  ``--host`` option to the ``openstack server migrate`` command.
+  
+  .. _Bug 1411190: https://bugs.launchpad.net/python-openstackclient/+bug/1411190
+
+.. releasenotes/notes/bug-1740232-91ad72c2ac165f35.yaml @ b'71f138b172e95515b9d54eee9b3e318df3381791'
+
+- Fix RuntimeError in ``project show`` command running under Python 3.
+  [Bug `1740232 <https://bugs.launchpad.net/python-openstackclient/+bug/1740232>`_]
+
+.. releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml @ b'415b48056d9d021e04ec972029040a89a6b13928'
+
+- Re-open stdout in binary mode before writing object data in
+  ``object save --file -`` command.
+  [Bug `1775482 <https://bugs.launchpad.net/python-openstackclient/+bug/1775482>`_]
+
+.. releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml @ b'04e03b2a1fe34046e2148d3c1d17b9053010c8af'
+
+- Fix ``endpoint group delete`` command to properly delete endpoint groups.
+  [Story `2005521 <https://storyboard.openstack.org/#!/story/2005521>`_]
+
+.. releasenotes/notes/bug-27882-402ced7ffe930058.yaml @ b'6f1f44d422ed3f384ea6d4d729227277f0988b99'
+
+- The ``--limit`` option of the ``image list`` command was previously ignored.
+  [Bug `2004314 <https://storyboard.openstack.org/#!/story/2004314>`_]
+
+
+.. _python-openstackclient_5.2.2-8:
+
+5.2.2-8
+=======
+
+.. _python-openstackclient_5.2.2-8_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml @ b'f0d21237a2de3d11ca68fee321dd0f8a724e1871'
+
+- Add ``--limit`` and ``--offset`` options to ``server group list`` command,
+  to configure pagination of results.
+
+.. releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml @ b'0a6babc04ce53a9234521e0549ba11b725d20bf7'
+
+- Add support for compute API microversion 2.47, which changes how flavor
+  details are included in server detail responses. In 2.46 and below,
+  only the flavor ID was shown in the server detail response. Starting in
+  2.47, flavor information is embedded in the server response. The newer
+  behavior is now supported.
+
+.. releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml @ b'89b4a689fc9c4b97b647636ef6db96268335954f'
+
+- Add ``--stateful`` and ``--stateless`` option to the
+  ``security group create`` and ``security group set`` commands
+  to support stateful and stateless security groups.
+
+
+.. _python-openstackclient_5.2.2-8_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml @ b'643b69d91480e461ff3546318943517b3226d11a'
+
+- Remove deprecated neutron-lbaas results from ``quota show`` command.
+
+
+.. _python-openstackclient_5.2.2:
+
+5.2.2
+=====
+
+.. _python-openstackclient_5.2.2_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml @ b'b30843cee35e50e516a41a48bcbe00dd2c1639f4'
+
+- You can now remove role assignments from keystone that reference non-existent
+  users or groups.
+  
+  [Bug `2006635 <https://storyboard.openstack.org/#!/story/2006635>`_]
+
+.. releasenotes/notes/task-40279-eb0d718ac1959c50.yaml @ b'5b25ea899e023bcd3d7384cca943f9844bcb0b79'
+
+- Makes ``volume backup record`` commands available in Volume API v3.
+  `Task 40279 <https://storyboard.openstack.org/#!/story/2007896>`__
+
+
+.. _python-openstackclient_5.2.1:
+
+5.2.1
+=====
+
+.. _python-openstackclient_5.2.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml @ b'19723aee18e2901e9250dd840a61359704baa170'
+
+- [Story `2005246 <https://storyboard.openstack.org/#!/story/2005246>`_]
+  The `is_domain` property safely handles type checking.
+
+
+.. _python-openstackclient_5.2.0:
+
+5.2.0
+=====
+
+.. _python-openstackclient_5.2.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/complete_image_switch-203e0b3105a54674.yaml @ b'768a64aac5bd14f56c142faeec1793aac91947cb'
+
+- Complete switch from glanceclient to the SDK for image service.
+
+.. releasenotes/notes/use_sdk_for_image-f49d2df38e7d9f81.yaml @ b'60e7c51df4cf061ebbb435a959ad63c7d3a296bf'
+
+- Image service for v2 is switched from using glanceclient to OpenStackSDK.
+
+
+.. _python-openstackclient_5.1.0:
+
+5.1.0
+=====
+
+.. _python-openstackclient_5.1.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-description-to-role-afe7b6ff668df261.yaml @ b'eb001733fd3c1a98027f7439b84e952f1eb2a406'
+
+- Now user can add the description when user create's
+  the role using OSC ``openstack role create`` command.
+  User can add the description by adding
+  `--description <Description>` to OSC
+  ``openstack role create`` command.
+
+.. releasenotes/notes/bug-1784879-9b632174d4af853f.yaml @ b'68aa35f35f21476085e25ad2e3da51a1961948e4'
+
+- Add ``--dns-publish-fixed-ip`` and ``--no-dns-publish-fixed-ip``
+  options to ``create subnet`` and ``set subnet`` commands to
+  control the publishing of fixed IPs in DNS when the
+  ``subnet_dns_publish_fixed_ip`` Neutron extension is enabled.
+  [Bug `1784879 <https://bugs.launchpad.net/neutron/+bug/1784879>`_]
+
+
+.. _python-openstackclient_5.1.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml @ b'962efd949feb461283a9bb4a668fbd310f80ba40'
+
+- For ``network create`` the
+  `--default`` option should be only used for external networks.
+  After this release, we enforce this scenario. If a users attempts
+  to create an internal default network or update a network to be
+  internal default, the command will be denied.
+  [Bug `1745658 <https://bugs.launchpad.net/bugs/1745658>`_]
+
+
+.. _python-openstackclient_5.0.0:
+
+5.0.0
+=====
+
+.. _python-openstackclient_5.0.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-parent-list-option-to-projects-10382a7176993366.yaml @ b'7c1b6a799e0ac6fea511a2cf1e97aebb2f94e0d6'
+
+- Add ``--parent`` option to ``project list`` command to filter projects
+  by the specified parent project.
+
+.. releasenotes/notes/add-server-migrate-confirm-revert-commands-9d8079c9fddea36d.yaml @ b'609988ebac2c6bbb596aa77b46589274ffbc1e07'
+
+- Add ``server migrate confirm`` and ``server migrate revert`` commands.
+  These are aliases of the ``server resize confirm`` and ``server resize revert``
+  commands, respectively.
+
+.. releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-9179045f04815bbb.yaml @ b'874a726f522dae3a08832f32230e2590a787d45c'
+
+- Add ``--disable-delete-on-termination`` and
+  ``--enable-delete-on-termination`` options to the ``server add volume``
+  command to indicate when to delete the attached volume when the server
+  is deleted.
+  Note that it requires ``--os-compute-api-version 2.79`` or greater.
+  [Blueprint support-specifying-az-when-restore-shelved-server `<https://blueprints.launchpad.net/nova/+spec/support-delete-on-termination-in-server-attach-volume>`_]
+
+.. releasenotes/notes/bp-whitelist-extension-for-app-creds-9afd5009b374190b.yaml @ b'70ab3f9dd56a638cdff516ca85baa5ebd64c888b'
+
+- [`blueprint whitelist-extension-for-app-creds <https://blueprints.launchpad.net/keystone/+spec/whitelist-extension-for-app-creds>`_]
+  Added support for creating access rules as an attribute of application
+  credentials as well as for listing, showing, and deleting access rules.
+
+
+.. _python-openstackclient_5.0.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/drop-py2-421c90fbdf18dbc2.yaml @ b'e6e4b73efa01281002930e0806b765200f38e7c8'
+
+- Python 2.7 support has been dropped. The last release of
+  python-openstackclient to support Python 2.7 is OpenStack Train. The
+  minimum version of Python now supported by python-openstackclient is
+  Python 3.6.
+
+
+.. _python-openstackclient_5.0.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml @ b'f5384ae16a24cdd54149fa21827d14b8b8983d4f'
+
+- Fixes the "No server with a name or ID of 'id' exists" error when running
+  ``server list --deleted --marker``. The fix removes using a name for
+  the marker when both ``--deleted`` and ``--marker`` are used. In
+  this scenario an ID must be supplied for the marker.
+  [Story `2006761 <https://storyboard.openstack.org/#!/story/2006761>`_]
+
+
+.. _python-openstackclient_5.4.0-14:
+
+5.4.0-14
+========
+
+.. _python-openstackclient_5.4.0-14_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml @ b'768dca5a695d78d8c5c22fca185137d3c5b8c07c'
+
+- Add ``--limit`` and ``--offset`` options to ``server group list`` command,
+  to configure pagination of results.
+
+.. releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml @ b'fef473390c7bb6874a38b98053e54cf18547b23c'
+
+- Add support for compute API microversion 2.47, which changes how flavor
+  details are included in server detail responses. In 2.46 and below,
+  only the flavor ID was shown in the server detail response. Starting in
+  2.47, flavor information is embedded in the server response. The newer
+  behavior is now supported.
+
+
+.. _python-openstackclient_5.4.0-14_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml @ b'8dbf141d52c84d0a7311e62d39d229fdc80876fd'
+
+- Stream image download to avoid buffering data in memory which rapidly exhausts memory resulting in OOM kill or system crash for all but the smallest of images. Fixes https://storyboard.openstack.org/#!/story/2007672
+
+.. releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml @ b'8dbf141d52c84d0a7311e62d39d229fdc80876fd'
+
+- Restore default behavior of 'openstack image save' to send data to stdout Relates to https://storyboard.openstack.org/#!/story/2007672.
+
+.. releasenotes/notes/story-2007727-69b705c561309742.yaml @ b'5a7841d5f04a76f6ab2ad01d6b41e01038ebd2a9'
+
+- The ``openstack server group create`` command will now validate the policy
+  value requested with ``--policy``, restricting it to the valid values
+  allowed by given microversions.
+
+
+.. _python-openstackclient_5.4.0-14_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml @ b'dd06a4c475a1813dc72bf439bfdcb47deec89049'
+
+- Remove deprecated neutron-lbaas results from ``quota show`` command.
+
+
+.. _python-openstackclient_5.4.0:
+
+5.4.0
+=====
+
+.. _python-openstackclient_5.4.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-port-numa-affinity-policy-4706b0f9485a5d4d.yaml @ b'454b2195649aec1a9eb1fdaa60b64663cb1f7298'
+
+- Add NUMA affinity policy to ``port create``, ``port set`` and
+  ``port unset`` commands.
+
+.. releasenotes/notes/properties-with-image-property-field.yaml-c51bf37c3106d6ff.yaml @ b'fbd2c00b8999202917671bcdb39298eb39c3ad47'
+
+- Support for image search via properties of image. Currently "openstack server create --image-property" only takes image property. Now it can also search image via properties (user defined) too. Story https://storyboard.openstack.org/#!/story/2007860.
+
+
+.. _python-openstackclient_5.4.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml @ b'e24673267093de85beee753860cda1fb224ce4bc'
+
+- You can now remove role assignments from keystone that reference non-existent
+  users or groups.
+  
+  [Bug `2006635 <https://storyboard.openstack.org/#!/story/2006635>`_]
+
+.. releasenotes/notes/security-grp-json-fix.yaml-2af1f48a48034d64.yaml @ b'bae89b30144fdf40d0fea31e1a595b507e32c4f3'
+
+- The ``openstack server show -f json`` command was not outputting json for security groups, volumes and properties  properly.
+
+
+.. _python-openstackclient_5.3.1:
+
+5.3.1
+=====
+
+.. _python-openstackclient_5.3.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml @ b'82ebddca006d1dc61855fdd34b0616222039ea58'
+
+- Fixes an issue with python 3.8 and entrypoint loading where the
+  new builtin importlib entrypoint support had a different
+  attribute api than expected.
+
+
+.. _python-openstackclient_5.3.0:
+
+5.3.0
+=====
+
+.. _python-openstackclient_5.3.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml @ b'74a7c1d9d6efc545676cec1d9efeb2a86c5bc548'
+
+- Add a new option `--description` to
+  ``floating ip port forwarding create`` and
+  ``floating ip port forwarding set`` commands.
+
+.. releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml @ b'c04ec16cf7ad2dbe7bf8edf5f6e7840c54b0efa3'
+
+- Added ``--import`` flag to ``openstack image create`` to allow
+  the user to force use of the image import codepath.
+
+.. releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml @ b'05da145eaee329e299b449ba2d7ea88d1325e432'
+
+- Added the below mentioned parameters to the user create and set commands.
+  
+  * --ignore-lockout-failure-attempts
+  * --no-ignore-lockout-failure-attempts
+  * --ignore-password-expiry
+  * --no-ignore-password-expiry
+  * --ignore-change-password-upon-first-use
+  * --no-ignore-change-password-upon-first-use
+  * --enable-lock-password
+  * --disable-lock-password
+  * --enable-multi-factor-auth
+  * --disable-multi-factor-auth
+  * --multi-factor-auth-rule
+  
+  This will now allow users to set user options via CLI.
+  <https://docs.openstack.org/keystone/latest/admin/resource-options.html#user-options>
+
+.. releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml @ b'7f66273d3f2fb6449d7b50d88460ace0cb81bf30'
+
+- Added the below mentioned parameters to the role, project and domain commands.
+  
+  * --immutable
+  * --no-immutable
+  
+  This will allow user to set "immutable" resource option.
+
+.. releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml @ b'b328cf74df7f94a20de85b3c0992dcb65e818458'
+
+- Add ``--force`` options to the ``openstack quota set`` command. The compute service allows us to to force set a quota, setting a quota value that is less than the amount of the resource currently consumed. Expose this feature by way of a ``--force`` boolean parameter.
+
+.. releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml @ b'f03cb68ad89dcc856fdad1a46fee36b7d68c5ba2'
+
+- Add ``address_scope`` as a valid ``--type`` value for the
+  ``network rbac create`` and ``network rbac list`` commands.
+
+.. releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml @ b'557e65d8ebaf7eaecb2f938d65feffa0e97a86d4'
+
+- Add ``subnetpool`` as a valid ``--type`` value for the
+  ``network rbac create`` and ``network rbac list`` commands.
+
+.. releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml @ b'dba57c85d5536369d600ae98599c08b921713bd5'
+
+- Add new commands ``router add route`` and ``router remove route`` to
+  support new Neutron extension: ``extraroute-atomic`` (see `Neutron RFE
+  <https://bugs.launchpad.net/neutron/+bug/1826396>`_).
+
+.. releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml @ b'5e62411e5f6c5b68512d1f72470b4222199eb456'
+
+- Add ``--stateful`` and ``--stateless`` option to the
+  ``security group create`` and ``security group set`` commands
+  to support stateful and stateless security groups.
+
+
+.. _python-openstackclient_5.3.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml @ b'dba57c85d5536369d600ae98599c08b921713bd5'
+
+- The use of ``router set --route`` to add extra routes next to already
+  existing extra routes is deprecated in favor of ``router add route
+  --route``, because ``router set --route`` if used from multiple clients
+  concurrently may lead to lost updates.
+
+
+.. _python-openstackclient_5.3.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml @ b'533af9f1b2de40d98f69e83cdf89ecf254cf3879'
+
+- [Story `2005246 <https://storyboard.openstack.org/#!/story/2005246>`_]
+  The `is_domain` property safely handles type checking.
+
+.. releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml @ b'c06d82563526c715d3ed508fa3cc5f9dc0963294'
+
+- While uploading a signed image, a private key to sign that image must be
+  specified. The CLI client asks for the password of that private key. Due
+  to wrong encoding handling while using Python 3, the password is not
+  accepted, whether it is correct or not.
+
+.. releasenotes/notes/task-40279-eb0d718ac1959c50.yaml @ b'b1fc587a6d4eac795a5bc27c2dffd2d876161caa'
+
+- Makes ``volume backup record`` commands available in Volume API v3.
+  `Task 40279 <https://storyboard.openstack.org/#!/story/2007896>`__
+
+
+.. _python-openstackclient_5.5.1-16:
+
+5.5.1-16
+========
+
+.. _python-openstackclient_5.5.1-16_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml @ b'4b7e777c0ce19aa67a9a33cbeb3b4ee2b052383f'
+
+- Add support for compute API microversion 2.47, which changes how flavor
+  details are included in server detail responses. In 2.46 and below,
+  only the flavor ID was shown in the server detail response. Starting in
+  2.47, flavor information is embedded in the server response. The newer
+  behavior is now supported.
+
+
+.. _python-openstackclient_5.5.1-16_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1946816-7665858605453578.yaml @ b'3f4142d5ddfca8c594d35bb0e5fd65009286d11b'
+
+- Filtering servers by tags (``server list --tag``,
+  ``server list --not-tag``) now works correctly.
+  [Bug `1946816 <https://bugs.launchpad.net/bugs/1946816>`_]
+
+.. releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml @ b'9425e6fcb6b907fbae7e1eb6b01ad293199cee75'
+
+- Fixed create image from volume command. If user wants to
+  pass ``visibility`` and ``protected`` fields, they need to
+  specify volume microversion 3.1 or greater by passing
+  ``os-volume-api-version 3.1`` with the command.
+
+.. releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml @ b'ecaa2805dcf8ea72729a1cfedb30eb60a66224b4'
+
+- Fixed a bug in "access rule" subcommands where the client logic incorrectly
+  assumed that access rules have a "name" property which resulted in
+  unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+  results in a not-found error instead of sometimes deleting an unrelated
+  rule.
+
+
+.. _python-openstackclient_5.5.0:
+
+5.5.0
+=====
+
+.. _python-openstackclient_5.5.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-image-progress-option-to-create-1ed1881d58ebad4b.yaml @ b'6f616a29b300238c004b676edd98a5337be38193'
+
+- Add ``--progress`` option to ``image create`` command to enable a progress
+  bar when creating and uploading an image.
+
+.. releasenotes/notes/add-image-project-filter-support-ed6204391e503adf.yaml @ b'3c80b1b3b29307381b869f6a767e14e9d47e212f'
+
+- Add ``--project`` and ``--project-domain``options to ``image list``
+  command to filter by owner.
+
+.. releasenotes/notes/add-keypairs-project-filter-99cb6938f247927f.yaml @ b'5645fad7622a18e4f3c550ee7d409bf1b685a1a5'
+
+- It is now possible to list the keypairs for all users in a project using
+  the ``--project`` parameter. This is an admin-only action by default and
+  requires Compute API microversion 2.10 or later.
+
+.. releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml @ b'98a0016cfa1d39bcc37144f0c7700e9a9d6b2c0b'
+
+- It is now possible to list the keypairs for a specific user using the
+  ``--user`` parameter. This is an admin-only action by default and requires
+  Compute API microversion 2.10 or later.
+
+.. releasenotes/notes/add-missing-hypervisor-list-opts-71da2cc36eac4edd.yaml @ b'262e525aada8bfaedb4545be5d2bbd27edcc55fd'
+
+- Add ``--limit`` and ``--marker`` options to ``hypervisor list`` command, to
+  configure pagination of results.
+
+.. releasenotes/notes/add-missing-keypair-list-opts-243a33d8276f91b8.yaml @ b'fc24142ed41e15622687558c68d670bdc37223f0'
+
+- Add ``--limit`` and ``--marker`` options to ``keypair list`` command, to
+  configure pagination of results.
+
+.. releasenotes/notes/add-missing-server-create-opts-d5e32bd743e9e132.yaml @ b'ace4bfb6404b7b39c597c4884c56e26a47a94fc4'
+
+- Add a number of additional options to the ``server create`` command:
+  
+  - ``--snapshot``
+  - ``--ephemeral``
+  - ``--swap``
+  - ``--block-device``
+
+.. releasenotes/notes/add-missing-server-delete-opts-071c3e054e3ce674.yaml @ b'8a164bb09c0801c3ffd2431d41c3e232388ab407'
+
+- Add ``--force`` option to ``server delete`` command, allowing users to
+  force delete a server. This is admin-only by default.
+
+.. releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml @ b'5ec4d4c7188f4766d270be32e12b64b709d2b835'
+
+- Add ``--limit`` and ``--offset`` options to ``server group list`` command,
+  to configure pagination of results.
+
+.. releasenotes/notes/add-missing-server-group-list-opts-ebcf84bfcea07a4b.yaml @ b'7ed4f68c68cb17b02deced203f9a461605a68dfe'
+
+- Add ``--limit``, ``--marker``, ``--change-since`` and ``--changes-before``
+  options to ``server group list`` command, to configure pagination of
+  results and filter results by last modification, respectively.
+
+.. releasenotes/notes/add-missing-server-image-create-opts-3c19a7492dc50fd7.yaml @ b'958344733aa6d8aea6cb8d06cc4d879fe1ee44a6'
+
+- Add ``--property`` option to ``server image create`` command, allowing
+  users to record arbitrary key/value metadata to ``meta_data.json`` on
+  the metadata server.
+
+.. releasenotes/notes/add-missing-server-list-opts-c41e97e86ff1e1ca.yaml @ b'd0112a801a20c810d92dfcdf1f8fb71df3bd1d26'
+
+- Add a number of additional options to the ``server list`` command:
+  
+  - ``--availability-zone``
+  - ``--key-name``
+  - ``--config-drive``, ``--no-config-drive``
+  - ``--progress``
+  - ``--vm-state``
+  - ``--task-state``
+  - ``--power-state``
+
+.. releasenotes/notes/add-missing-server-rebuild-opts-5c75e838d8f0487d.yaml @ b'f9fd3642f8e8c59cd5a819e260d0575f884ae174'
+
+- Add a number of additional options to the ``server rebuild`` command:
+  
+  - ``--name``
+  - ``--preserve-ephemeral``, ``--no-preserve-ephemeral``
+  - ``--user-data``, ``--no-user-data``
+  - ``--trusted-image-cert``, ``--no-trusted-image-certs``
+
+.. releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml @ b'8a0f3fc6a8b30328c575bb5c3fc21ddc4f500d9d'
+
+- Add ``--no-password`` option to ``server set`` command, allowing users
+  to clear the admin password from the metadata service. Note that this does
+  not actually change the server password.
+
+.. releasenotes/notes/add-project-cleanup-beb08c9df3c95b24.yaml @ b'119d2fae2567285b9149b2c737d7d4452b59288c'
+
+- Add support for project cleanup based on the OpenStackSDK with
+  create/update time filters. In the long run this will replace
+  `openstack project purge` command.
+
+.. releasenotes/notes/add-server-evacuate-8359246692cb642f.yaml @ b'01eb4e839394fe433a92a06daf1499fb00f2fe69'
+
+- Add ``server evacuate`` command. This command will recreate an instance
+  from scratch on a new host and is intended to be used when the original
+  host fails.
+
+.. releasenotes/notes/add-server-migration-show-command-2e3a25e383dc5d70.yaml @ b'f80fe2d8cf50f85601e2895a5f878764fa77c154'
+
+- Add ``server migration show`` commands. This can be used to show detailed
+  information about an ongoing server migration.
+
+.. releasenotes/notes/add-server-nic-tagging-support-f77b4247e87771d5.yaml @ b'9ed34aac0a172ece4cd856319486208fcdba095d'
+
+- The ``--nic`` option of the ``server create`` command now supports an
+  optional ``tag=<tag>`` key-value pair. This can be used to set a tag for
+  the interface in server metadata, which can be useful to maintain
+  persistent references to interfaces during various operations.
+
+.. releasenotes/notes/add-server-volume-update-89740dca61596dd1.yaml @ b'ca7f23d0d1876dc53ef4d5ecbf2c5f367aafe13e'
+
+- Add ``server volume list`` command, to list the volumes attached to an
+  instance.
+
+.. releasenotes/notes/add-server-volume-update-89740dca61596dd1.yaml @ b'ca7f23d0d1876dc53ef4d5ecbf2c5f367aafe13e'
+
+- Add ``server volume update`` command, to update the volumes attached to
+  an instance.
+
+.. releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml @ b'2b073c2034acdabb8d4097b7f2c0408e53fe2d63'
+
+- Add support for ``--offload`` and ``--wait`` options for ``server shelve``.
+  ``--offload`` allows users to explicitly request offloading of a shelved
+  server in environments where automatic offloading is not configured, while
+  ``--wait`` allows users to wait for the shelve and/or shelve offload
+  operations to complete.
+
+.. releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml @ b'2b073c2034acdabb8d4097b7f2c0408e53fe2d63'
+
+- Add support ``--wait`` option for ``server shelve``.
+
+.. releasenotes/notes/add-tag-support-server-add-fixed-ip-8de2db58f2a80e85.yaml @ b'742c80a82574e5a6928c305842047b8b6b2b3807'
+
+- Add ``--tag`` option to ``server add fixed ip`` command when adding a fixed IP to server. Only available starting with ``--os-compute-api-version 2.49``.
+
+.. releasenotes/notes/add-tag-support-server-add-network-a8590cab5d7babf0.yaml @ b'6f1602312b00bcba6e04a34f7f04af9d69cf2d9c'
+
+- Add ``--tag`` option to ``server add network`` command when add network to server. Only available starting with ``--os-compute-api-version 2.49``.
+
+.. releasenotes/notes/add-tag-support-server-add-port-7e30aa38202d0839.yaml @ b'f3fbb1b648a96e541b53f96904b85d3fdce2af10'
+
+- Add ``--tag`` option to ``server add port`` command when add a port to server. Only available starting with ``--os-compute-api-version 2.49``.
+
+.. releasenotes/notes/add-tag-support-server-add-volume-278e79a22dd482f4.yaml @ b'1c7fe3b6bd60aa22ae525d0418729590f6429e96'
+
+- Add ``--tag`` option to ``server add volume`` command when add a volume to server. Only available starting with ``--os-compute-api-version 2.49``.
+
+.. releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml @ b'1e053babf4d674ac31d51dfba048704f32b558b3'
+
+- Add ``--id`` and ``--enabled`` option to ``identity provider list`` command.
+
+.. releasenotes/notes/add_name_and_enabled_to_list_domain-6d23f02994b51c67.yaml @ b'8628e52de7412e57e13238ad1ba7113deb6a2e1b'
+
+- Add ``--name`` and ``--domain`` option to ``domain list`` command.
+
+.. releasenotes/notes/always-show-direction-for-sg-rule-130efc39bf67d79a.yaml @ b'e410e61d204d09eeb7bcf0a33e3858ef7b110dd3'
+
+- By default listing security group rules now shows the direction.
+  The ``--long`` argument is now redundant and is now ignored as it
+  was only used to display the direction.
+
+.. releasenotes/notes/auto-configure-block-live-migration-437d461c914f8f2f.yaml @ b'2bdf34dcc3f8957ff78709467197b5fcb44e07c3'
+
+- The ``server migrate`` command will now automatically determine whether
+  to use block or shared migration during a live migration operation. This
+  requires Compute API microversion 2.25 or greater.
+
+.. releasenotes/notes/bp-add-user-id-field-to-the-migrations-table-299b99ccb1f12a1f.yaml @ b'b77c28d2954a2c5861a3a6a1df29d8de448f7c08'
+
+- Add ``server migration list`` command. This command allows
+  users to list the status of ongoing server migrations.
+
+.. releasenotes/notes/bp-address-groups-in-sg-rules-b3b7742e4e6f5745.yaml @ b'e01e59caeb56cb7bf4f38403b82d0a265b163098'
+
+- Add ``--remote-address-group`` option to ``security group rule create``
+  command for using an address group as the source/destination in security
+  group rules. Also add field ``remote_address_group_id`` to the output of
+  ``security group rule show`` and add column ``Remote Address Group`` to
+  the output of ``security group rule list``.
+  [Blueprint `address-groups-in-sg-rules <https://blueprints.launchpad.net/neutron/+spec/address-groups-in-sg-rules>`_]
+
+.. releasenotes/notes/bp-address-groups-in-sg-rules-e0dc7e889e107799.yaml @ b'f57e10b903fa71d02a6e104717824d004178bbf5'
+
+- Add ``address group create``, ``address group delete``, ``address group list``, ``address group set``, ``address group show`` and ``address group unset`` commands to support Neutron address group CRUD operations. [Blueprint `address-groups-in-sg-rules <https://blueprints.launchpad.net/neutron/+spec/address-groups-in-sg-rules>`_]
+
+.. releasenotes/notes/bug-1708570-bb19e1213e887723.yaml @ b'fd9a235de3b3592366818ab7799e73f6be029b15'
+
+- Add ``--password`` option to ``server create`` command, allowing users to
+  set the admin password when creating a new instance.
+
+.. releasenotes/notes/bug-2007489-42e41b14e42128ce.yaml @ b'1c3cf11331a5734700e1c333c98928ab933c0e92'
+
+- Add ``server migration abort`` command to abort ongoing live migrations.
+
+.. releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml @ b'08b0e5855be5dc12a2fd04c5c92027c8a85a0d00'
+
+- Add ``server migration force complete`` command to force complete ongoing live migrations.
+
+.. releasenotes/notes/flavor-list-min-disk-min-ram-65ba35e7acc24134.yaml @ b'da03bd80e3b83faf465f1446c4553c5d97b5bad5'
+
+- The ``openstack flavor list`` command now accepts two additional
+  options, ``--min-disk`` and ``--min-ram``, to filter flavor by
+  minimum disk and minimum RAM, respectively.
+
+.. releasenotes/notes/keypair-support-type-6f7c32aab3b61f7b.yaml @ b'4855fef8b8f29542ebdaf86aa5da4daa1f97b060'
+
+- Add ``--key-type`` option to ``keypair create`` command to set keypair type. Can be ssh or x509. Note that ``--os-compute-api-version 2.2`` or later is required.
+
+.. releasenotes/notes/keypair-user-id-db694210695a0ee0.yaml @ b'17f641e1c3ac58acdc39d064369395198d2654d2'
+
+- Add ``--user`` option to the ``keypair create``, ``keypair delete``, and
+  ``keypair show`` commands. Only available starting with
+  ``--os-compute-api-version 2.10``.
+
+.. releasenotes/notes/port-device-profile-4a3bf800da21c778.yaml @ b'0cc878e5b053765a0d3c13f5588bc160b05a388b'
+
+- Add device profile to ``port create`` command.
+
+.. releasenotes/notes/rbac-add-address-group-f9bb83238b5a7c1f.yaml @ b'e8509d81ee0b541033411e744f633e769073530b'
+
+- Add ``address_group`` as a valid ``--type`` value for the
+  ``network rbac create`` and ``network rbac list`` commands.
+
+.. releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml @ b'2f76bfa3a69b6867491a6c5f0bf3c7e9f62743ca'
+
+- Add ``--tag`` option to ``server create`` command to add tags when creating a server. Only available starting with ``--os-compute-api-version 2.52``.
+
+.. releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml @ b'2f76bfa3a69b6867491a6c5f0bf3c7e9f62743ca'
+
+- Add ``--tag`` option to ``server set`` command to add a tag to an existing server. Only available starting with ``--os-compute-api-version 2.26``.
+
+.. releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml @ b'2f76bfa3a69b6867491a6c5f0bf3c7e9f62743ca'
+
+- Add ``--tag`` options to ``server unset`` command to remove a tag from an existing server. Only available starting with ``--os-compute-api-version 2.26``.
+
+.. releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml @ b'2f76bfa3a69b6867491a6c5f0bf3c7e9f62743ca'
+
+- Add ``--tags`` and ``--not-tags`` options to ``server list`` command to list instances with and without the specified tag(s), respectively. Only available starting with ``--os-compute-api-version 2.26``.
+
+.. releasenotes/notes/server-group-create_rule_option-9f84e52f35e7c3ba.yaml @ b'a5c6470f2d76afb9ac87d05c4326bebf925a55da'
+
+- Add support for ``--rule`` option for ``server group create``.
+
+.. releasenotes/notes/server-list-selectable-fields.yaml-1d5fb4784fa6f232.yaml @ b'311f4130d2c59638074531fa59e67783c2571e91'
+
+- Add ``--c project_id | user_id | created_at`` to ``openstack server list`` command to get these columns as an output.
+
+.. releasenotes/notes/server-ops-all-projects-2ce2202cdf617184.yaml @ b'1a6df700be2507bcec760994e64042d03b09ae16'
+
+- The ``server delete``, ``server start`` and ``server stop`` commands now
+  support the ``--all-projects`` option. This allows you to perform the
+  specified action on a server in another project using the server name.
+  This is an admin-only action by default.
+
+.. releasenotes/notes/show-server-topology-microversion-v2_78-3891fc67f767177e.yaml @ b'f200799848831a00f350c324bb77c00efa50da1c'
+
+- Add support for ``openstack server show --topology`` flag, which will
+  include NUMA topology information in the output.
+
+.. releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml @ b'f36a34b675e69a811d5cd48f6bcfd6ce7bda6a5a'
+
+- Switch aggregate operations to use SDK
+
+.. releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml @ b'f36a34b675e69a811d5cd48f6bcfd6ce7bda6a5a'
+
+- Adds 'aggregate cache image' operation
+
+.. releasenotes/notes/switch-console-log-to-sdk-6ee92b7833364d3d.yaml @ b'74db8dd65d35b326d3fa1c680b04a668a3f66bdc'
+
+- Switch console logs operation to use SDK
+
+.. releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml @ b'0f4f42b65281b9b8b4f8fc3e58da8c9d8b68ee08'
+
+- Switch compute.flavor operations from direct API calls (novaclient) to OpenStackSDK.
+
+
+.. _python-openstackclient_5.5.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/add-missing-server-list-opts-c41e97e86ff1e1ca.yaml @ b'd0112a801a20c810d92dfcdf1f8fb71df3bd1d26'
+
+- The ``openstack server list --status`` parameter will now validate the
+  requested status.
+
+.. releasenotes/notes/add-missing-server-rebuild-opts-5c75e838d8f0487d.yaml @ b'f9fd3642f8e8c59cd5a819e260d0575f884ae174'
+
+- The ``--key-unset`` option of the ``server rebuild`` command has been
+  replaced by ``--no-key-name``. An alias is provided.
+
+.. releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml @ b'8a0f3fc6a8b30328c575bb5c3fc21ddc4f500d9d'
+
+- The ``server set --root-password`` option has been deprecated in favour of
+  a non-interactive ``--password`` option.
+
+.. releasenotes/notes/deprecated-server-create-file-option-80246b13bd3c1b43.yaml @ b'6f3969a0c8a608236a6f7258aa213c12af060a9d'
+
+- The ``server create`` command will now error out if the ``--file`` option
+  is specified alongside ``--os-compute-api-version`` of ``2.57`` or greater.
+  This reflects the removal of this feature from the compute service in this
+  microversion.
+
+.. releasenotes/notes/remove-deprecated-server-migrate-live-option-28ec43ee210124dc.yaml @ b'70480fa86236f7de583c7b098cc53f0acedfd91d'
+
+- The deprecated ``--live`` option of the ``server migrate`` command has
+  been removed. This was problematic as it required a host argument and
+  would result in a forced live migration to a host, bypassing the
+  scheduler. It has been replaced by a ``--live-migration`` option and
+  optional ``--host`` option.
+
+.. releasenotes/notes/rename-server-migrate-confirm-revert-commands-84fcb937721f5c4a.yaml @ b'a52beacaa6fcc11d48f5b742c73aa2c0f87634ce'
+
+- The ``server migrate confirm`` and ``server migrate revert`` commands,
+  introduced in OSC 5.0, have been deprecated in favour of
+  ``server migration confirm`` and ``server migration revert`` respectively.
+  The deprecated commands will be removed in a future major version.
+
+.. releasenotes/notes/warn-on-disk-overcommit-087ae46f12d74693.yaml @ b'8868c77a201703edaded5d06aa1734265431f786'
+
+- A warning will now be emitted when using the ``--disk-overcommit``
+  or ``--no-disk-overcommit`` flags of the ``server migrate`` command on
+  Compute API microversion 2.25 or greater. This feature is only supported
+  before this microversion and previously the flag was silently ignored on
+  newer microversions. This warning will become an error in a future
+  release.
+
+
+.. _python-openstackclient_5.5.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/add-missing-server-create-opts-d5e32bd743e9e132.yaml @ b'ace4bfb6404b7b39c597c4884c56e26a47a94fc4'
+
+- The ``--block-device-mapping`` option of the ``server create`` command
+  has been deprecated in favour of ``--block-device``. The format of the
+  ``--block-device-mapping`` option is based on the limited "BDM v1"
+  format for block device maps introduced way back in the v1 nova API. The
+  ``--block-device`` option instead exposes the richer key-value based
+  "BDM v2" format.
+
+.. releasenotes/notes/always-show-direction-for-sg-rule-130efc39bf67d79a.yaml @ b'e410e61d204d09eeb7bcf0a33e3858ef7b110dd3'
+
+- Deprecate the ``--long`` option for the ``security group list``
+  command. This is no longer needed to display all columns.
+
+.. releasenotes/notes/story-2005468-server-use-config-drive-9fc68552365cfefa.yaml @ b'12f1e56ebf2ea3999c57246410501c09fced2c4c'
+
+- The ``--config-drive`` option on the ``openstack server create`` command
+  has been deprecated in favour of the ``--use-config-drive`` and
+  ``--no-config-drive`` arguments. The ``--config-drive`` option expected
+  either a string or bool-like argument, but the nova API has only supported
+  boolean values since API v2.1 was introduced.
+
+
+.. _python-openstackclient_5.5.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-flavor-props-formatting-d21e97745543caa7.yaml @ b'ad3369ed1fdad73b5d457a40df7df8ad55eb69cd'
+
+- Fix '-f json' output of the flavor properties to return valid json object instead of stringying it.
+
+.. releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml @ b'5bdcd590ecacbc0aa8db2cbafa0ab1a9f3c28ce0'
+
+- Stream image download to avoid buffering data in memory which rapidly exhausts memory resulting in OOM kill or system crash for all but the smallest of images. Fixes https://storyboard.openstack.org/#!/story/2007672
+
+.. releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml @ b'5bdcd590ecacbc0aa8db2cbafa0ab1a9f3c28ce0'
+
+- Restore default behavior of 'openstack image save' to send data to stdout Relates to https://storyboard.openstack.org/#!/story/2007672.
+
+.. releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml @ b'bf834f6d7582009672fc65aa983f314684dc4380'
+
+- The ``addresses`` and ``flavor`` fields of the ``server show`` command will
+  now be correctly rendered as a list of objects and an object, respectively.
+
+.. releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml @ b'bf834f6d7582009672fc65aa983f314684dc4380'
+
+- The ``networks`` and ``properties`` fields of the ``server list`` command
+  will now be rendered as objects. In addition, the ``power_state`` field
+  will now be humanized and rendered as a string value when using the table
+  formatter.
+
+.. releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml @ b'bf834f6d7582009672fc65aa983f314684dc4380'
+
+- The ``usage list`` and ``usage show`` commands will now display the name
+  of the project being queried rather than the ID when using the table
+  formatter. In addition, the ``server_usages``, ``total_memory_mb_usage``,
+  ``total_vcpus_usage`` and ``total_local_gb_usage`` values will only be
+  humanized when using the table formatter.
+
+.. releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml @ b'bf834f6d7582009672fc65aa983f314684dc4380'
+
+- The ``policies`` (or ``policy``, on newer microversions) and ``members``
+  fields of the ``server group list`` and ``server group show`` commands
+  will now be rendered correctly as lists.
+
+.. releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml @ b'bf834f6d7582009672fc65aa983f314684dc4380'
+
+- The ``cpu_info`` field of the ``hypervisor show`` output is now
+  correctly decoded and output as an object.
+
+.. releasenotes/notes/restore-create-image-duplicates-92e06f64038b120c.yaml @ b'17678c9bd6f3f4c5b9e7b5ceb27c2bd12493fba4'
+
+- Fixes default behaviour of `openstack image create` in allowing images
+  with the same name. In version 5.2.0 this changed to not allow
+  duplicates by default.
+
+.. releasenotes/notes/story-2004346-add-floating-ip-with-no-ports-399c5559e1699816.yaml @ b'415545ab9fd842bdc19b7fbfa63e3332dd63fe6c'
+
+- Associating a floating IP with a server using the ``server add floating
+  ip`` command requires the server have at least one port associated with it.
+  Previously, this was not validated, meaning the operation would silently
+  fail. This has been resolved.
+
+.. releasenotes/notes/story-2007727-69b705c561309742.yaml @ b'bb15b29190dfe77ea0218a01edc1f4886993b177'
+
+- The ``openstack server group create`` command will now validate the policy
+  value requested with ``--policy``, restricting it to the valid values
+  allowed by given microversions.
+
+.. releasenotes/notes/subnet-unset-gateway-20239d5910e10778.yaml @ b'ed731d6cd9254eae047d14ccd55132229e13e7d1'
+
+- Add missing ``openstack subnet unset --gateway <subnet-id>``.
+
+
+.. _python-openstackclient_5.5.0_Other Notes:
+
+Other Notes
+-----------
+
+.. releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml @ b'e9bd4ef007153e4f2e2d69f3bcb94eef8e8983c2'
+
+- Remove deprecated neutron-lbaas results from ``quota show`` command.
+
+
+.. _python-openstackclient_5.6.2-4:
+
+5.6.2-4
+=======
+
+.. _python-openstackclient_5.6.2-4_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml @ b'560f19b8948acb15bc8510a4be6bdfe7d353a9d6'
+
+- Fixed a bug in "access rule" subcommands where the client logic incorrectly
+  assumed that access rules have a "name" property which resulted in
+  unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+  results in a not-found error instead of sometimes deleting an unrelated
+  rule.
+
+
+.. _python-openstackclient_5.6.1:
+
+5.6.1
+=====
+
+.. _python-openstackclient_5.6.1_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml @ b'0873e7580eceab07c3be0824d2ea4163491f8d6e'
+
+- Add support for compute API microversion 2.47, which changes how flavor
+  details are included in server detail responses. In 2.46 and below,
+  only the flavor ID was shown in the server detail response. Starting in
+  2.47, flavor information is embedded in the server response. The newer
+  behavior is now supported.
+
+
+.. _python-openstackclient_5.6.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1946816-7665858605453578.yaml @ b'cbc64f9469600624e74631f42ca214487e800155'
+
+- Filtering servers by tags (``server list --tag``,
+  ``server list --not-tag``) now works correctly.
+  [Bug `1946816 <https://bugs.launchpad.net/bugs/1946816>`_]
+
+.. releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml @ b'665d93ff0721801896bf08c3cc4f189a55daae80'
+
+- Fixed create image from volume command. If user wants to
+  pass ``visibility`` and ``protected`` fields, they need to
+  specify volume microversion 3.1 or greater by passing
+  ``os-volume-api-version 3.1`` with the command.
+
+
+.. _python-openstackclient_5.6.0:
+
+5.6.0
+=====
+
+.. _python-openstackclient_5.6.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/L3-conntrack-helper-bd0d9da041747e84.yaml @ b'fa8c8d26a7696d169b0b9d5aaf6b723d8feee08a'
+
+- Add new commands ``network l3 conntrack helper create``,
+  ``network l3 conntrack helper set``, ``network l3 conntrack helper show``,
+  ``network l3 conntrack helper set`` and
+  ``network l3 conntrack helper delete`` to support Neutron L3 conntrack
+  helper CRUD operations.
+
+.. releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml @ b'7f66dfe0e3e8720e847211494c185d7d4983ba5b'
+
+- Add ``--no-incremental``, ``--property`` and ``--availability-zone``
+  options to ``volume backup create`` command, allowing users to request a
+  non-incremental backup, set a metadata property on the created backup, and
+  set an availability zone on the created backup, respectively.
+
+.. releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml @ b'7f66dfe0e3e8720e847211494c185d7d4983ba5b'
+
+- Add ``--property`` and ``--no-property`` options to the
+  ``volume backup set`` command to set a metadata property or remove all
+  metadata properties from an existing backup.
+
+.. releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml @ b'7f66dfe0e3e8720e847211494c185d7d4983ba5b'
+
+- Add new ``volume backup unset`` command to allow unsetting of properties
+  from an existing volume backup.
+
+.. releasenotes/notes/add-volume-attachment-commands-db2974c6460fa3bc.yaml @ b'6dc94e1fb85595653dcdd24185c914b9df1741df'
+
+- Add ``volume attachment create``, ``volume attachment delete``,
+  ``volume attachment list``, ``volume attachment complete``,
+  ``volume attachment set`` and ``volume attachment show`` commands to
+  create, delete, list, complete, update and show volume attachments,
+  respectively.
+
+.. releasenotes/notes/add-volume-group-commands-b121d6ec7da9779a.yaml @ b'af406f33e38a8e9a5fb3c58e34f0d55c1d4d1d74'
+
+- Add ``volume group create``, ``volume group delete``,
+  ``volume group list``, ``volume group failover``,
+  ``volume group set`` and ``volume attachment show``
+  commands to create, delete, list, failover, update and show volume groups,
+  respectively.
+
+.. releasenotes/notes/add-volume-group-snapshot-commands-27fa8920d55f6bdb.yaml @ b'34de2d3352aaef5c1bb86a5441cc8781e03b5587'
+
+- Add ``volume group snapshot create``, ``volume group snapshot delete``,
+  ``volume group snapshot list`` and ``volume group snapshot show`` commands
+  to create, delete, list, and show volume group snapshots, respectively.
+
+.. releasenotes/notes/add-volume-group-type-commands-13eabc7664a5c2bc.yaml @ b'83551d2a0c7604179c0988c13d58455a6b289cc8'
+
+- Add ``volume group type create``, ``volume group type delete``,
+  ``volume group type list``, ``volume group type set/unset`` and
+  ``volume group type show`` commands to create, delete, list, update,
+  and show volume group types, respectively.
+
+.. releasenotes/notes/add-volume-message-commands-89a590a1549c333e.yaml @ b'0eddab36e52e813e2329ac10044fa4f67830efec'
+
+- Add ``volume message list``, ``volume message get`` and
+  ``volume message delete`` commands, to list, get and delete volume
+  failure messages, respectively.
+
+.. releasenotes/notes/add-volume-transfer-request-create-snapshots-opts-1361416d37021e89.yaml @ b'a821d6b7c57c7684a990ee39b6b93d5085f25a70'
+
+- The ``volume transfer request create`` command now accepts the
+  ``--snapshots`` / ``--no-snapshots`` option to configure whether to
+  create a transfer request for a volume without snapshots or not.
+
+.. releasenotes/notes/compute-service-list-forced-down-2b16d1cb44f71a08.yaml @ b'12c93c6d5ff420f6a4a8833d33bad6ee7222e2f7'
+
+- Add column ``Forced Down`` to the output of ``compute service list
+  --long``. Only available starting with ``--os-compute-api-version 2.11``.
+
+.. releasenotes/notes/implements-hide-image-4c726a61c336ebaa.yaml @ b'383289edd8ea222ce1a6e77ed0298ecdb21608a1'
+
+- Add mutually exclusive options ``--hidden`` and ``--unhidden`` to
+  ``image set`` command to hide or unhide an image (``is_hidden``
+  attribute).
+
+.. releasenotes/notes/implements-hide-image-4c726a61c336ebaa.yaml @ b'383289edd8ea222ce1a6e77ed0298ecdb21608a1'
+
+- Add option ``--hidden`` to ``image list`` command to list hidden images.
+
+.. releasenotes/notes/network-port-create-vnic-type-vdpa-fc02516cfb919941.yaml @ b'6f821659795fdc82c694bb9fdddd5d3c61702e21'
+
+- The ``port create --vnic-type`` option now accepts a ``vdpa`` value.
+
+
+.. _python-openstackclient_5.6.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml @ b'7f66dfe0e3e8720e847211494c185d7d4983ba5b'
+
+- The ``--name`` and ``--description`` options of the ``volume backup set``
+  command will now verify the version requested on the client side.
+  Previously this would fail on the server side.
+
+
+.. _python-openstackclient_5.8.1:
+
+5.8.1
+=====
+
+.. _python-openstackclient_5.8.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml @ b'849e7e93f83a220265d11af71e2edc009c3f7bea'
+
+- Fixed create image from volume command. If user wants to
+  pass ``visibility`` and ``protected`` fields, they need to
+  specify volume microversion 3.1 or greater by passing
+  ``os-volume-api-version 3.1`` with the command.
+
+.. releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml @ b'f4748f4d250d4d8eb592b7170f1e020f9ece8df3'
+
+- Fixed a bug in "access rule" subcommands where the client logic incorrectly
+  assumed that access rules have a "name" property which resulted in
+  unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+  results in a not-found error instead of sometimes deleting an unrelated
+  rule.
+
+
+.. _python-openstackclient_5.8.0:
+
+5.8.0
+=====
+
+.. _python-openstackclient_5.8.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-network-local-ip-df3a9ce7610d8b90.yaml @ b'26144743d9207d876df40e030a2a4132e18a79a7'
+
+- Add ``local ip create``, ``local ip delete``, ``local ip list``, ``local ip set``, ``local ip show``, ``local ip association create``, ``local ip association delete`` and ``local ip association list`` commands to support Neutron Local IP CRUD operations. [`bug 1930200 <https://bugs.launchpad.net/neutron/+bug/1930200>`_]
+
+.. releasenotes/notes/add-option-to-unset-port-host-c76de9b1d2addf9a.yaml @ b'f4629331134c40599f9baf908a391460b74d2767'
+
+- Add possibility to unbind Neutron's port from the host by unsetting its
+  host_id.
+
+.. releasenotes/notes/add-remote-managed-vnic-type-4fc540b47427c37f.yaml @ b'd565f110938f46224ada92c3d68ca416f05635b6'
+
+- Support for the ``remote-managed`` VNIC type has been added and can now be
+  passed to the ``--vnic-type`` option when used in conjunction with the
+  ``port create`` and ``port set`` commands.
+
+.. releasenotes/notes/check-limit-quota-cc7f291dd1b537c1.yaml @ b'bef70397a3e1240cc593b3fb34049f2ff6601e68'
+
+- Add ``--check-limit`` option to the ``openstack quota set`` command (only for network commands). The network quota engine will check the resource usage before setting the new quota limit.
+
+.. releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml @ b'8e362402dee07744668bcf7f6774af4fbe9a07e3'
+
+- Add support for compute API microversion 2.47, which changes how flavor
+  details are included in server detail responses. In 2.46 and below,
+  only the flavor ID was shown in the server detail response. Starting in
+  2.47, flavor information is embedded in the server response. The newer
+  behavior is now supported.
+
+.. releasenotes/notes/list-subnet-by-pool-id-a642efc13d04fa08.yaml @ b'e4e9fb594d003ea6c3ec29aab0bccf72ffab6781'
+
+- Add ``--subnet-pool`` option to ``subnet list`` to filter
+  by subnets by subnet pool.
+
+.. releasenotes/notes/migrate-add-fixed-ip-to-sdk-3d932d77633bc765.yaml @ b'9971d7253e9c3abd2e3940bf549ef8532ef929f9'
+
+- Switch the add fixed IP command from novaclient to SDK.
+
+.. releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml @ b'9acbd3e1052d533c1395eb59de4274170baed67b'
+
+- Migrate openstack server image create from novaclient to sdk.
+
+.. releasenotes/notes/migrate-server-add-network-add-port-to-sdk-7d81b25f59cfbec9.yaml @ b'2183a611475090347863917f6c90f0f38cd80893'
+
+- Migrate server add network/port from novaclient to openstacksdk.
+
+.. releasenotes/notes/migrate-server-add-volume-to-sdk-685e036a88839651.yaml @ b'3078a0a121743c387d83d7f27ce3d8fd8fbb4ccf'
+
+- Migrate openstack server add volume to using sdk.
+
+.. releasenotes/notes/migrate-server-pause-unpause-to-sdk-d74ec8536b764af6.yaml @ b'b515fe61b27408e78639da8abb3acaa485ebca4e'
+
+- Migrate ``server pause`` and ``server unpause`` commands from novaclient
+  to sdk.
+
+.. releasenotes/notes/migrate-server-suspend-resume-to-sdk-fd1709336607b496.yaml @ b'ff96fea0120ab43968a10230ce7899a3c6504e75'
+
+- Migrate ``server suspend`` and ``server resume`` commands from novaclient
+  to sdk.
+
+.. releasenotes/notes/migrate-service-list-delete-set-to-sdk-920cbe0d210af565.yaml @ b'b5a2714b83d4ce1991aae775381dcfb02ff59e9d'
+
+- Switch the compute service commands from novaclient to SDK.
+
+.. releasenotes/notes/options-create-router-97910a882b604652.yaml @ b'4e9b9298429f5db505987853f98d2388b6745b13'
+
+- It is now possible to add an external gateway to a router
+  immediately on creation. Previously it could only be done by
+  modifying the router after it had been created. This includes
+  the options to en- or disable SNAT and to specify a fixed-ip
+  on the external network.
+
+.. releasenotes/notes/pass_ssh_args-cf26a2ce26ccddaf.yaml @ b'3a929611c0ec5dd8e7bf24692984d1df8b9a97f8'
+
+- Added the ability to pass arguments through to the ``ssh`` command When
+  using ``openstack server ssh``. This allows the user to use any ``ssh``
+  option without needing to add that option to the openstack client.
+  Existing openstackclient options that mirror SSH options are now
+  deprecated.
+
+.. releasenotes/notes/port-list-security-group-4af5d2e789174ff9.yaml @ b'c8c4f76498de3380c7cbf80c5dc800a588bed649'
+
+- Added ``--security-group`` option to the ``os port list`` command. This
+  option is appendable and multiple security group IDs can be provided.
+
+.. releasenotes/notes/switch-server-remove-network-port-to-sdk-829ba711e0e198d5.yaml @ b'f82afc7f379daebd1994d9133eff801f790c0d32'
+
+- Switch server remove volume/port to using sdk.
+
+.. releasenotes/notes/switch-server-remove-volume-to-sdk-47e9befd2672dcdf.yaml @ b'fae293dd5218cf4ea03d0a4c44d17b97987dea12'
+
+- Switch command server remove volume to using sdk.
+
+
+.. _python-openstackclient_5.8.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/pass_ssh_args-cf26a2ce26ccddaf.yaml @ b'3a929611c0ec5dd8e7bf24692984d1df8b9a97f8'
+
+- ``openstack server ssh`` options that mirror ``ssh`` options are now
+  deprecated (``--login, -l, --port, --identity, --option, -o, -vz``).
+  The ``ssh`` equivalent of each deprecated option should be used instead.
+  For example ``openstack server ssh instance -- -l user -i key``
+
+
+.. _python-openstackclient_5.7.0:
+
+5.7.0
+=====
+
+.. _python-openstackclient_5.7.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-server-hostname-opts-3cb4fd90b5bf47ca.yaml @ b'8e833a3ed26467a1190ba69d8ba716a7cd1cccb3'
+
+- The ``server create``, ``server set`` and ``server rebuild`` commands now
+  accept an optional ``--hostname HOSTNAME`` option. This can be used to
+  configure the hostname stored in the metadata service and/or config drive.
+  Utilities such as ``cloud-init`` can then consume this information to set
+  the hostname within the guest OS.
+
+.. releasenotes/notes/add-trusted-certs-option-server-create-a660488407300f22.yaml @ b'28a376bfb0a330470b028b6d5244ee4c8e1fe864'
+
+- Added ``--trusted-image-cert`` option for server create. It is available
+  only when directly booting server from image (not from volume, not from
+  snapshot and not via image converted to volume first).
+  This option is supported for Compute API version >=2.63
+
+.. releasenotes/notes/add_attachment_id_to_volume_attachment-cea605585db29e14.yaml @ b'51ee17a94dccd297101725593b223f01c4f9b906'
+
+- Added support for `microversion 2.89`_. This microversion removes the
+  ``id`` field while adding the ``attachment_id`` and ``bdm_uuid`` fields to
+  the responses of ``GET /servers/{server_id}/os-volume_attachments`` and
+  ``GET /servers/{server_id}/os-volume_attachments/{volume_id}`` with these
+  changes reflected in novaclient under the ``openstack server volume list``
+  command.
+  
+  .. _microversion 2.89: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-89
+
+.. releasenotes/notes/migrate-server-backup-to-sdk-0f170baf38e98b40.yaml @ b'57aad01886fe9d98210496a92d517aa067c049a1'
+
+- Migrate openstack server backup from novaclient to sdk.
+
+.. releasenotes/notes/show-result-for-server-add-volume-f75277ad58e31024.yaml @ b'163cb01e46fc3f906154a7045fdbe9342cd446c7'
+
+- The ``server add volume`` command will now return details of the created
+  volume attachment upon successful attachment.
+
+
+.. _python-openstackclient_5.7.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-1946816-7665858605453578.yaml @ b'53debe7fe1978f661768a27430f646a288948ecc'
+
+- Filtering servers by tags (``server list --tag``,
+  ``server list --not-tag``) now works correctly.
+  [Bug `1946816 <https://bugs.launchpad.net/bugs/1946816>`_]
+
+
+.. _python-openstackclient_6.0.1:
+
+6.0.1
+=====
+
+.. _python-openstackclient_6.0.1_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-reimage-param-to-rebuild-606dd331677b5954.yaml @ b'7d702baf171dba9942db44a3814ce2c9575b2fe2'
+
+- The ``server rebuild`` commands now accept two optional
+  ``--reimage-boot-volume`` and ``--no-reimage-boot-volume``option.
+  Passing these parameter will allow/disallow a user to rebuild a volume
+  backed server.
+  This is available from Compute microversion ``2.93`` and onwards.
+
+
+.. _python-openstackclient_6.0.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml @ b'48148e7a1197c92febdb3ab1e72085c4eb3d6bf7'
+
+- Fixed a bug in "access rule" subcommands where the client logic incorrectly
+  assumed that access rules have a "name" property which resulted in
+  unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+  results in a not-found error instead of sometimes deleting an unrelated
+  rule.
+
+
+.. _python-openstackclient_6.0.0:
+
+6.0.0
+=====
+
+.. _python-openstackclient_6.0.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-block-storage-cluster-commands-fae8f686582bbbcf.yaml @ b'd727a6502369a6a7244ef1c07c1c483dbe0a8dab'
+
+- Add ``block storage cluster create``, ``block storage cluster delete``,
+  ``block storage cluster list`` and ``block storage cluster show`` commands
+  to create, delete, list, and show block storage service clusters,
+  respectively.
+
+.. releasenotes/notes/bug-1597189-02a8d8a402725860.yaml @ b'de4a69a29ff4657d0c3cd95ca9f35ff24f653b5f'
+
+- The ``volume`` argument of the ``volume backup restore`` command is now
+  optional and can refer to the name of a new volume that should be created
+  rather than a name or ID of an existing volume (which would be
+  overwritten). If not provided, cinder will generate a new volume with a
+  unique name. To restore a backup to an existing volume, you must now
+  specify the ``--force`` option (volume v2, v3 only).
+  [Bug `1597189 <https://bugs.launchpad.net/bugs/1597189>`_]
+
+.. releasenotes/notes/image-list-multiple-tags-a394799c7807f031.yaml @ b'5cc6fc2b88296035f687f72d92efe4a3cea78fc7'
+
+- The ``image list`` now accepts multiple ``--tag`` options, allowing you to
+  filter images on more than one tag.
+
+.. releasenotes/notes/qos-min-pps-rule-bfe22cea1966c4a0.yaml @ b'6ccbcdde64670daaaac4f42fe62eb180df700905'
+
+- Add support for QoS minimum packet rate rule to following commands:
+  ``network qos rule create``, ``network qos rule delete``,
+  ``network qos rule list``, ``network qos rule show`` and
+  ``network qos rule set``
+
+.. releasenotes/notes/quota-network-force-920913981b45ba1a.yaml @ b'1c6d396ba30c1a92a417f778d7522ea43e9b2d4a'
+
+- Add ``--force`` options to the ``openstack quota set`` command for network service commands. Neutron quota engine now accepts "force" flag to set a new resource quota limit, regardless of the current resource usage.
+
+.. releasenotes/notes/server-list-host-status-1f542a5bc4292a62.yaml @ b'93578ef85ba5f94ec5dc8fc4b2917e91c74121da'
+
+- The ``server list`` command will now display ``Host Status`` when the
+  ``--long`` option is specified and the compute API microversion is 2.16 or
+  greater.
+
+.. releasenotes/notes/server-migration-by-uuid-59f8272f63abee5d.yaml @ b'cffec4517f8bfbe3a6d6d1610c5b3217271a9a9f'
+
+- The ``server migration abort``, ``server migration force complete`` and
+  ``server migration show`` commands will now accept a server migration UUID
+  in addition to an ID.
+
+
+.. _python-openstackclient_6.0.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml @ b'9eea28ba59e44526b9d6f1ad9f80c3553d5853e2'
+
+- Fixed create image from volume command. If user wants to
+  pass ``visibility`` and ``protected`` fields, they need to
+  specify volume microversion 3.1 or greater by passing
+  ``os-volume-api-version 3.1`` with the command.
+
+.. releasenotes/notes/volume-attachment-create-output-fix-56515b8fcdd260b9.yaml @ b'045f2e7e0618fdf22c260625d64554382afefde1'
+
+- The ``volume attachment create`` command will now display information
+  for successfully created volume attachments. Previously an empty table was
+  returned.
+
+
+.. _python-openstackclient_2023.1-eom:
+
+2023.1-eom
+==========
+
+.. _python-openstackclient_2023.1-eom_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml @ b'a03e3dbf75c55561bc3575c53db445868be87a3b'
+
+- Fixed a bug in "access rule" subcommands where the client logic incorrectly
+  assumed that access rules have a "name" property which resulted in
+  unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+  results in a not-found error instead of sometimes deleting an unrelated
+  rule.
+
+
+.. _python-openstackclient_6.2.0:
+
+6.2.0
+=====
+
+.. _python-openstackclient_6.2.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-port-ranges-in-port-forwarding-command-8c6ee05cf625578a.yaml @ b'bced4852c7a92959f5457360dd91eb397af4d270'
+
+- Add port ranges support to the ``floating ip port forwarding`` commands.
+
+.. releasenotes/notes/migrate-host-list-show-to-sdk-9b80cd9b4196ab01.yaml @ b'ecc6aeeede68db65cb888390dd9299a4cfad6630'
+
+- The ``host list`` and ``host show`` commands have been migrated to SDK.
+
+.. releasenotes/notes/migrate-server-volume-list-update-to-sdk-95b1d3063e46f813.yaml @ b'25b4714f1cd12c20ff7653f05dddb5486a037fcc'
+
+- Switch the server volume list and server volume update command from novaclient to SDK.
+
+.. releasenotes/notes/switch-server-migration-show-to-sdk-4adb88a0f1f03f3b.yaml @ b'd1c1c36af15d8cfc43b26b239324b48b0924b66e'
+
+- Finish switching server migration to the OpenStackSDK
+
+
+.. _python-openstackclient_6.2.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/consistency-group-create-opts-aliases-e1c2f1498e9b1d3d.yaml @ b'4106926fa65622dc33e7322832394aedb47f95ad'
+
+- The ``--consistency-group-source`` and ``--consistency-group-snapshot``
+  options for the ``consistency group create`` command have been renamed to
+  ``--source`` and ``--snapshot``, respectively. Aliases are provided for the
+  older variants.
+
+.. releasenotes/notes/rename-server-volume-update-to-server-volume-set-833f1730a9bf6169.yaml @ b'e0577e7ebe359ff241023b64055f777f8504d3af'
+
+- The ``server volume update`` command has been renamed to ``server volume
+  set`` to better match other commands in OSC. An alias is provided for
+  backwards compatibility.
+
+
+.. _python-openstackclient_6.2.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/deprecate-volume-group-create-positional-arguments-89f6b886c0f1f2b5.yaml @ b'0d57f3f367163dc4d3b57ae574a825563494f133'
+
+- The ``<volume-group-type>`` and ``<volume-type> [<volume-type>...]``
+  positional arguments for the ``volume group create`` command have been
+  deprecated in favour of option arguments. For example::
+  
+      openstack volume group create \
+        --volume-group-type <volume-group-type>
+        --volume-type <volume-type> [--volume-type <volume-type> ...]
+
+
+.. _python-openstackclient_6.1.0:
+
+6.1.0
+=====
+
+.. _python-openstackclient_6.1.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-backup-option-to-create-vol-fc36c2c745ebcff5.yaml @ b'bd0727c4f897289722ba639930c9e979cfee534a'
+
+- Added ``--backup`` option to the ``volume create`` command.
+
+.. releasenotes/notes/add-baremetal-agent-type-7c46365e8d457ac8.yaml @ b'b7d01833d02260006e6d4c6e0a065748ecc8b913'
+
+- Add ``baremetal`` agent type to ``--agent-type`` option for
+  ``network agent list`` command.
+
+.. releasenotes/notes/add-block-storage-manage-commands-6ebf029bd7a67bb3.yaml @ b'73b4ce88eb3e71568cf5330d6c0a8a4e92287d89'
+
+- Added ``block storage volume manageable list`` and
+  ``block storage snapshot manageable list`` commands that
+  allow operators to list the volumes and snapshots on a
+  particular host or cluster for management under OpenStack.
+
+.. releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml @ b'ec01268ea93141439542fb162a6a12bc2bf533fe'
+
+- Added ``--source-group`` and ``--group-snapshot`` options to the
+  ``volume group create`` command to allow creating group from
+  a source group or a group snapshot.
+
+.. releasenotes/notes/add-image-metadef-namespace-support-4ba37ec3a1a72185.yaml @ b'a726d84f4b7cec761d3d82824997969dffbd4249'
+
+- Adds ``openstack image metadef namespace list``. The output is equivalent to glance md-namespace-list.
+
+.. releasenotes/notes/add-image-task-commands-50c3643ebfd0421f.yaml @ b'c9d445fc4baf036793103b15c9eb2632da3610e0'
+
+- Add ``image task show`` command to show a task for the image service.
+
+.. releasenotes/notes/add-image-task-commands-50c3643ebfd0421f.yaml @ b'c9d445fc4baf036793103b15c9eb2632da3610e0'
+
+- Add ``image task list`` command to list tasks for the image service.
+
+.. releasenotes/notes/add-missing-trust-list-opts-500fd1e4c14e1504.yaml @ b'64e4520b2a79b9046a791f5e3729f5cbfc2d3fa5'
+
+- Add missing ``--trustee``, ``--trustee-domain``, ``--trustor``,
+  ``--trustor-domain`` options to ``trust list`` command, to allow
+  filtering trusts by trustee and trustor.
+
+.. releasenotes/notes/add-missing-trust-list-opts-500fd1e4c14e1504.yaml @ b'64e4520b2a79b9046a791f5e3729f5cbfc2d3fa5'
+
+- Add ``--authuser`` option to ``trust list`` command, to allow
+  displaying only trusts related to current authenticated user
+
+.. releasenotes/notes/add-network-rbac-list-tenant-project-filter-1228f2287284e33c.yaml @ b'4d7d7e627eb4bb028251bd7993026aae45db7d8b'
+
+- Add a new argument ``--target-project`` to the ``network rbac list``
+  command to filter for a specific target project.
+
+.. releasenotes/notes/add-reimage-param-to-rebuild-606dd331677b5954.yaml @ b'4024bdb3933dd79eec4bcf99c13f3dbf17add40b'
+
+- The ``server rebuild`` commands now accept two optional
+  ``--reimage-boot-volume`` and ``--no-reimage-boot-volume``option.
+  Passing these parameter will allow/disallow a user to rebuild a volume
+  backed server.
+  This is available from Compute microversion ``2.93`` and onwards.
+
+.. releasenotes/notes/add-vol-service-get-set-log-commands-f9420e5061d994b5.yaml @ b'a9e3049e9ce8a6e2d46152ef85ad6679b8cb8f1d'
+
+- Added ``block storage log level list`` and ``block storage log level set``
+  commands that allows operators to list and set log levels for cinder
+  services.
+
+.. releasenotes/notes/add-volume-revert-command-1c8f695420acbe7e.yaml @ b'e7ebf7544b7bd0b014e9dffa27d6c4c63f078f6e'
+
+- Added ``volume revert`` command that reverts
+  the volume to the given snapshot.
+
+.. releasenotes/notes/add-volume-summary-command-b2175b48af3ccab1.yaml @ b'77266bd9c3afd94a7043d0fa85075671e7a16b93'
+
+- Added ``volume summary`` command to show the total size,
+  total count and metadata of volumes.
+
+.. releasenotes/notes/add-workers-cleanup-command-720573c0f642efe9.yaml @ b'2be359677908b81d9985917fd78f9c6897759fb9'
+
+- Added ``block storage cleanup`` command that allows cleanup
+  of resources (volumes and snapshots) by services in other nodes
+  in a cluster in an Active-Active deployments.
+
+.. releasenotes/notes/add_volume_backend_commands_to_volumeV3-145b114e40ab8615.yaml @ b'f0f54f01001db657b3ed7d618dfd1078f2dde580'
+
+- Support of two commands was added in volume v3: "volume backend capability
+  show" and "volume backend pool list". These commands are present in v2
+  volume, but still absent in v3.
+
+.. releasenotes/notes/auto-no-network-options-f4ddb2bb7544d2f5.yaml @ b'a7975c42003d7df2af91154007435cd5f8560f24'
+
+- The ``server create`` command now accepts two new options, ``--no-network``
+  and ``--auto-network``. These are aliases for ``--nic none`` and
+  ``--nic auto``, respectively.
+
+.. releasenotes/notes/bp-unshelve-to-host-9ce4b7abf81aeedf.yaml @ b'6e0699c1cf3e603850580a6bb5ca2e377fe1bc84'
+
+- Add ``--host`` and ``--no-availability-zone`` options to the ``server unshelve`` command to enable administrators to specify a destination host or unset the availability zone during a server unshelve, respectively. Both options require the server to be shelved offload and ``--os-compute-api-version 2.91`` or greater.
+
+.. releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml @ b'44443f78561ce4f23d202a42de4a4ceac2ffa097'
+
+- The ``quota list`` command can now provide detailed quotas for the volume
+  service, e.g.::
+  
+      $ openstack quota list --detail --volume
+
+.. releasenotes/notes/idp-auth-ttl-6632df5db65a3bdd.yaml @ b'167cf11e825af95fe40c1daefdb6095c791a3ee5'
+
+- ``identity provider create`` and ``identity provider set`` commands now
+  accept the ``--authorization-ttl <VALUE>`` argument, with ``<VALUE>``
+  being a non-negative integer.
+  
+  See `note <https://docs.openstack.org/keystone/latest/admin/federation/configure_federation.html#create-a-mapping>`_
+  in Keystone documentations for more details on the meaning of this option.
+
+.. releasenotes/notes/image-import-d5da3e5ce8733fb0.yaml @ b'4eea3408dc492e948671b625ffc4379212b5857c'
+
+- Add ``image import`` command, allowing users to take advantage of the
+  interoperable image import functionality first introduced in Glance 16.0.0
+  (Queens).
+
+.. releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml @ b'38f972fa637871de8ab2ad4a70780faef6833198'
+
+- Add ``openstack image metadef namespace create`` command to create metadef namespace for the image service.
+
+.. releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml @ b'38f972fa637871de8ab2ad4a70780faef6833198'
+
+- Add ``openstack image metadef namespace delete`` command to delete image metadef namespace.
+
+.. releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml @ b'38f972fa637871de8ab2ad4a70780faef6833198'
+
+- Add ``openstack image metadef namespace set`` command to update metadef namespace for the image service.
+
+.. releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml @ b'38f972fa637871de8ab2ad4a70780faef6833198'
+
+- Add ``openstack image metadef namespace show`` command to show metadef namespace for the image service.
+
+.. releasenotes/notes/image-stage-ac19c47e6a52ffeb.yaml @ b'1fb8d1f48b256a2bad78e7d5633ea53c6537907c'
+
+- Added a new command, ``image stage``, that will allow users to upload data
+  for an image to staging.
+
+.. releasenotes/notes/network-ndp-proxy-cli-19afc530fc7061e2.yaml @ b'b36cd0f4c0416182ce69d71a4e99d89507d53e7f'
+
+- Add new commands ``router ndp proxy create``, ``router ndp proxy set``,
+  ``router ndp proxy show``, ``router ndp proxy list`` and
+  ``router ndp proxy delete`` to support Neutron NDP proxy CRUD operations.
+
+.. releasenotes/notes/network-ndp-proxy-cli-19afc530fc7061e2.yaml @ b'b36cd0f4c0416182ce69d71a4e99d89507d53e7f'
+
+- Add new options ``--enable-ndp-proxy`` and ``--disable-ndp-proxy`` to
+  command ``router create`` and ``router set`` to support Neutron NDP proxy
+  feature.
+
+.. releasenotes/notes/network-qos-rule-type-filters-47f4911a02011501.yaml @ b'bfab0199bebf139be5a948fdf8ced868b3e942de'
+
+- Added two new filter flags to ``openstack network qos rule type list``:
+  ``--all-supported``, to return any QoS rule type supported by at least
+  one loaded driver; ``--all-rules``, to return all QoS rule types
+  supported by the current version of Neutron server, regardless of the
+  loaded drivers.
+
+.. releasenotes/notes/no-force-limit-quota-cc7f291dd1b537c1.yaml @ b'09ff9a0f4c118f50924d2fc078d6a4501e696224'
+
+- Add ``--no-force`` option to the ``openstack quota set`` command (only for compute and network commands). When specified, the compute and network quota engine will check the resource usage before setting the new quota limit. This is the default behavior of the compute quota engine and will become the default for the network quota engine in a future release.
+
+.. releasenotes/notes/nova-gaps-server-list-to-sdk-88c8bfc10a9e3032.yaml @ b'c97f73ce2a897fe6b83f08de1ce6e1865e9a83c5'
+
+- The ``server list`` command now uses the OpenStack SDK instead of the
+  Python nova bindings.
+
+.. releasenotes/notes/optional-volume-name-ffbefe463a598b6c.yaml @ b'3fc585332f79358489285eabc298e01007599128'
+
+- The ``<name>`` argument for the ``volume create`` command is now optional.
+
+.. releasenotes/notes/quota-delete-947df66ae5341cbf.yaml @ b'45bec041b206678de36f2f463ac6872b785e592e'
+
+- Added a new command, ``quota delete``, that will allow admins delete quotas
+  set for projects. Supported by the compute, volume, and network services.
+
+.. releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml @ b'00e7019022585bc2be9aeb55eb40b1d04776ec22'
+
+- The ``quota show`` command now allows you to show quotas for a specific
+  service using the ``--compute``, ``--volume``, or ``--network`` options.
+
+.. releasenotes/notes/quota-show-usage-option-19b1f59fb5f3498f.yaml @ b'04e68e0d5a49be93f79d6d71821ab8cd0b0ce589'
+
+- The ``quota show`` command now supports a ``--usage`` option. When
+  provided, this will result in the command returning usage information for
+  each quota. This replaces the ``quota list --detail`` command which is now
+  deprecated for removal.
+
+.. releasenotes/notes/server-list-restrict-images-c0b2c4de6f93df33.yaml @ b'725b7de13cf00da386132a42b2738f4c57026184'
+
+- The ``server list`` needs to query the image service API to retrieve
+  image names as part of the response. This command will now retrieve only
+  the images that are relevant, i.e. those used by the server included in
+  the output. This should result in signficantly faster responses when
+  using a deployment with a large number of public images.
+
+.. releasenotes/notes/switch-hypervisor-to-sdk-2e90b26a14ffcef3.yaml @ b'006e35509d3cea66dc13fe2238dac92f47fe3c5c'
+
+- Switch hypervisor to the OpenStackSDK
+
+.. releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml @ b'992cfdfb57c359f709a0ceb67502f5bd66b90e5a'
+
+- Switch hypervisor operations to consume OpenStackSDK
+
+.. releasenotes/notes/switch-server-migration-to-sdk-4e4530f787f90fd2.yaml @ b'86c54701348d519139c52722197d262c35f7ea8e'
+
+- The ``server migration *`` commands now use the OpenStackSDK instead of
+  novaclient.
+
+.. releasenotes/notes/switch-server-show-to-sdk-44a614aebf2c6da6.yaml @ b'70dbb01ea3ed900a41092d46ed5ae1370d5771af'
+
+- The ``server show`` command now uses the OpenStack SDK instead of the
+  Python nova bindings. The command prints data fields both by their
+  novaclient names used in previous releases as well as the names used in the
+  SDK.
+
+
+.. _python-openstackclient_6.1.0_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+.. releasenotes/notes/deprecated-quota-class-options-ba33a45caedbdf3e.yaml @ b'b62021260c9c2d372ea635a2a7f0608b7c8472e1'
+
+- The ``--class`` options of the ``quota show`` and ``quota set`` commands
+  are now deprecated. Quota classes were never fully implemented and the
+  compute and volume services only support a single ``default`` quota class
+  while the network service does not support quota classes at all. The
+  default quotas can be changed on a deployment-wide basis via configuration
+  and can be inspected using the ``openstack quota show --default`` command.
+  Quotas can still be set on a project-specific basis using the ``quota set``
+  command.
+
+.. releasenotes/notes/no-force-limit-quota-cc7f291dd1b537c1.yaml @ b'09ff9a0f4c118f50924d2fc078d6a4501e696224'
+
+- The ``openstack quota set`` command currently defaults to ``--force`` behavior for network quotas. This behavior is now deprecated and a future release will switch to ``--no-force`` behavior. Users should explicitly specify one of these options to prevent a potentially breaking change in behavior.
+
+.. releasenotes/notes/quota-show-usage-option-19b1f59fb5f3498f.yaml @ b'04e68e0d5a49be93f79d6d71821ab8cd0b0ce589'
+
+- The ``--detail`` option for the ``quota list`` command has been deprecated
+  for removal. When used without the ``--detail`` option, the ``quota list``
+  command returned quota information for multiple projects yet when used with
+  this option it only returned (detailed) quota information for a single
+  project. This detailed quota information is now available via the
+  ``quota show --usage`` command.
+
+.. releasenotes/notes/quota-show-usage-option-19b1f59fb5f3498f.yaml @ b'04e68e0d5a49be93f79d6d71821ab8cd0b0ce589'
+
+- The ``--project`` option for the ``quota list`` command has been deprecated
+  for removal. Use the ``quota show`` command instead.
+
+
+.. _python-openstackclient_6.1.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2010376-e15362bdd6c8d6ec.yaml @ b'91277e7e51849d197554b633a579c92116a5afc4'
+
+- The ``server create`` command will no longer insist on an ``--image``,
+  ``--image-property``, ``--volume`` or ``--snapshot`` argument when a
+  volume is provided with a boot index of ``0`` via the ``--block-device``
+  option.
+
+.. releasenotes/notes/story-2010343-b5eb4ed593f51d3f.yaml @ b'ec8dba29f9f646ec05c0d6fad32b4b3aaf99f6af'
+
+- The ``flavor list`` command will no longer attempt to fetch extra specs
+  unless they are actually required (by using the ``--long``) option. This
+  should significantly improve performance on clouds with a large number of
+  flavors.
+  [Story `2010343 <https://storyboard.openstack.org/#!/story/2010343>`_]
+
+
+.. _python-openstackclient_6.3.0:
+
+6.3.0
+=====
+
+.. _python-openstackclient_6.3.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-auto-approve-cleanup-a2d225faa42dfdcb.yaml @ b'7506eb8e0c459494bdb4ec47de2e18a2a953d727'
+
+- An ``--auto-approve`` option has been added to the
+  ``project cleanup`` command. This allows the interactive
+  confirmation of resource deletion to be skipped.
+
+.. releasenotes/notes/add-flavor-id-to-router-create-76e916e129b5b80c.yaml @ b'f8f174c458a8a33e1c7279cc3266ef0087378a86'
+
+- Add the ``--flavor-id`` option to the ``router create`` command.
+
+.. releasenotes/notes/add-image-metadef-resource-type-list-command-020adcaa2ad14e07.yaml @ b'52bf194741c2594f38539ae63d3ea3fe05152a09'
+
+- Added ``image metadef resource type list`` command. This is equivalent to
+  the ``+md-namespace-resource-type-list`` command in glanceclient.
+
+.. releasenotes/notes/add-import-info-stores-delete-c50b5222c21e1077.yaml @ b'b347347986ebc8677c1d656299020fe58b1dc2a3'
+
+- Add ``image import info`` command, allowing users to know available import
+  methods, and `--store` option to ``image delete``, allowing users to delete
+  image from particular store.
+
+.. releasenotes/notes/add-port-hints-attribute-be1779e640a47d0d.yaml @ b'22d1a26d1dfd53a4337d541354544031ec6fdd17'
+
+- Enable management of Neutron port hints: ``port create --hint HINT``,
+  ``set port --hint HINT and ``unset port --hint``. Port hints allow
+  passing backend specific hints to Neutron mainly to tune backend
+  performance. The first hint controls Open vSwitch Tx steering.
+
+.. releasenotes/notes/add-stores-info-9f1488dd29013767.yaml @ b'18a6199ed0dc9d173ff18302b85615143077a887'
+
+- Add ``image stores info`` command, allowing users to know available backends.
+
+.. releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml @ b'629eb33c4dcb73d44d1a4c6105e40d28f6cebdfc'
+
+- Add ``--no-property`` option in ``volume qos set``.
+
+.. releasenotes/notes/add-volume-type-set-public-private-opts-891fc7ab5de9bb6a.yaml @ b'83f5c8033fa2a29dde422215277befd0ec63290e'
+
+- The ``volume type set`` command now supports ``--public`` and ``--private``
+  options.
+
+.. releasenotes/notes/keypair-create-client-side-generation-73d8dd36192f70c9.yaml @ b'2454636386d443473dedff1f07f8623108e87298'
+
+- The ``openstack keypair create`` command will now generate keypairs on the
+  client side in ssh-ed25519 format. The Compute service no longer supports
+  server-side key generation starting with ``--os-compute-api-version 2.92``
+  while the use of ssh-ed25519 is necessary as support for ssh-rsa has been
+  disabled by default starting in OpenSSH 8.8, which prevents its use in
+  guests using this version of OpenSSH in the default configuration.
+  ssh-ed25519 support is widespread and is supported by OpenSSH 6.5 or later
+  and Dropbear 2020.79 or later.
+
+.. releasenotes/notes/migrate-backup-commands-0becc8f18cf9737b.yaml @ b'bfd6170b03ab5c20cafdc96443cd73b3e8f3ae82'
+
+- Migrated the following backup commands to SDK:
+  
+  * Create Backup
+  * Show Backup
+  * List Backup
+  * Restore Backup
+  * Delete Backup
+
+.. releasenotes/notes/migrate-server-events-to-sdk-6a1f5dce582df245.yaml @ b'737540cca0b820ceaf53fc74e81f4fdafbc8f518'
+
+- The ``server event list`` and ``server event show`` commands have been
+  migrated to SDK.
+
+.. releasenotes/notes/migrate-server-reboot-to-sdk-a49822810def4c8a.yaml @ b'864f51f427c01d13c8408782dd03be4b473f7b2e'
+
+- Migrate ``server reboot`` command from novaclient to SDK.
+
+.. releasenotes/notes/migrate-server-restore-to-sdk-4540f26753031779.yaml @ b'004b2ab2fbad3655915f226ca2f479b35f7bfc46'
+
+- The ``server restore`` command has been migrated to SDK.
+
+.. releasenotes/notes/migrate-server-shelve-unshelve-to-sdk-8fce77586aa68a51.yaml @ b'f56f0e333ed5873f72be6ee554e8f18499dbb00b'
+
+- The ``server shelve`` and ``server unshelve`` commands have been migrated
+  to SDK.
+
+.. releasenotes/notes/migrate-server-start-stop-to-sdk-55edd4e1ff5e6ac7.yaml @ b'9241514137cd8d45fa6f36808536c5d0f218cb97'
+
+- Migrate ``server start`` and ``server stop`` commands from novaclient to
+  sdk.
+
+.. releasenotes/notes/migrate-volume-revert-to-sdk-1e399853d80ba5f8.yaml @ b'aaeda25e28ba27c7e5d1870eba448e94e4a8aa1b'
+
+- The ``volume revert`` command has been migrated to SDK.
+
+.. releasenotes/notes/migrate-volume-summary-to-sdk-96ff58f653e0feaa.yaml @ b'4dfbc5011efe6b5cd30d5eac20b8cf29003004b2'
+
+- The ``volume summary`` command has been migrated to SDK.
+
+.. releasenotes/notes/project-cleanup-skip-resource-option-4f80db0d8cf36fdb.yaml @ b'f29e3ccc37a510c40ea61216ac3a7e3ef944e1bf'
+
+- A new option ``--skip-resource`` has been added to the
+  ``project cleanup`` command. This allows to exclude
+  certain resources from project cleanups, e. g.
+  ``--skip-resource "block_storage.backup"`` to keep
+  Cinder backups.
+
+.. releasenotes/notes/story-2010751-server-rebuild-wait-shutoff-c84cddcd3f15e9ce.yaml @ b'417a7ad2039c09adbd497392c0199b7667e65ef7'
+
+- ``openstack server rebuild`` command now fails early if the server is
+  not in a state supported for rebuild - either ``ACTIVE``, ``ERROR`` or
+  ``SHUTOFF``.
+  See `OpenStack Compute API reference for server rebuild action
+  <https://docs.openstack.org/api-ref/compute/?expanded=rebuild-server-rebuild-action-detail#rebuild-server-rebuild-action>`_.
+
+.. releasenotes/notes/switch-server-lock-to-sdk-d5dd17e4987233a5.yaml @ b'ce8171bad90f15ac8a753f50bb3792862b66cc7c'
+
+- The ``server lock`` and ``server unlock`` commands now use SDK.
+
+
+.. _python-openstackclient_6.3.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/remove-project-purge-d372374b1a7c4641.yaml @ b'601d9717c2a5c125912ca27e43259c48e548939b'
+
+- The ``project purge`` command has been removed. This has been superseded by
+  the ``project cleanup`` command, was not tested, and has not been
+  functional for some time hence its removal without a deprecation period.
+  The replacement is ``project cleanup``, which is more powerful and more
+  flexible.
+
+
+.. _python-openstackclient_6.3.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml @ b'bc60e3bb908a7f10c87993d791184bfe46784d6c'
+
+- Fixed a bug in "access rule" subcommands where the client logic incorrectly
+  assumed that access rules have a "name" property which resulted in
+  unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+  results in a not-found error instead of sometimes deleting an unrelated
+  rule.
+
+.. releasenotes/notes/story-2010751-server-rebuild-wait-shutoff-c84cddcd3f15e9ce.yaml @ b'417a7ad2039c09adbd497392c0199b7667e65ef7'
+
+- ``openstack server rebuild --wait`` now properly works for servers in
+  ``SHUTOFF`` state without hanging.
+  [Story `2010751 <https://storyboard.openstack.org/#!/story/2010751>`_]
+
+
+.. _python-openstackclient_6.6.0:
+
+6.6.0
+=====
+
+.. _python-openstackclient_6.6.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-image-metadef-object-update-f4880e423bf4faba.yaml @ b'3cd5ad2c1babc9bddc85c1faf5005728a909725c'
+
+- Add ``image metadef object update`` command which
+  updates the attributes of an object.
+
+
+.. _python-openstackclient_6.5.0:
+
+6.5.0
+=====
+
+.. _python-openstackclient_6.5.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-image-member-get-25e913ef2b861bf3.yaml @ b'93b2e66d2dd245d36774a2725d6786ef325ae35b'
+
+- Add ``image member get`` command which accepts an
+  image_id and member_id and displays the detail of
+  the particular meber associated to the image.
+
+.. releasenotes/notes/add-port-hardware-offload-type-011c98ab748357d7.yaml @ b'0725bb474c138c84cbe1131cbf5ab5d877f9d964'
+
+- Add the port hardware offload attribute to the ``port create`` command.
+  Once defined, the value cannot be modified.
+
+.. releasenotes/notes/server-create-server-group-a5b630f2a64de28d.yaml @ b'7708106cf06cd590ca581802d55094418bdc1feb'
+
+- The ``server create`` command now accepts a new option, ``--server-group``,
+  which is a shortcut for configuring the ``group`` scheduler hint.
+
+
+.. _python-openstackclient_6.4.0:
+
+6.4.0
+=====
+
+.. _python-openstackclient_6.4.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/Add-default-security-group-rule-CRUD-2916568f829ea38c.yaml @ b'7b99b5716544bccf455ad0bf6d8a0ccfe2788331'
+
+- Add ``default security group rule create``, ``default security group rule
+  delete``, ``default security group rule list`` and ``default security group
+  rule show`` commands to support Neutron Default Security Group Rule CRUD
+  operations.
+  [Bug `1983053 <https://bugs.launchpad.net/bugs/1983053>`_]
+
+.. releasenotes/notes/add-cache-commands-a6f046348a3a0b1f.yaml @ b'c628c2dcd3efb6cde7d6322ce7fa405508e2e487'
+
+- Add commands for the image Cache API, to list, queue,
+  delete and clear images in the cache.
+
+.. releasenotes/notes/add-metadef-object-create-3939ee1453585484.yaml @ b'f8c708900c7c522d12b2ca95e0c335219db75bf8'
+
+- Add ``image metadef object show`` command to create the
+  metadata definitions objects inside a specific namespace
+
+.. releasenotes/notes/add-metadef-object-list-c8831e73c696b9d9.yaml @ b'4bb6efa8f8ec60f288b1e7a246e97dacb0f6ad33'
+
+- Add ``image metadef object list`` command to list the
+  metadata definitions objects inside a specific namespace
+
+.. releasenotes/notes/add-metadef-object-show-1b05dd33ecf42210.yaml @ b'78ef009a3aebe43583d6b93e65f53c49a1d818a6'
+
+- Add ``image metadef object show`` command to show the
+  metadata definitions objects inside a specific namespace
+
+.. releasenotes/notes/add-metadef-property-create-c9a4ec2bced892af.yaml @ b'd9c4c43a409977ed593169011b103b618302cc08'
+
+- Add ``image metadef property create`` command to create a new
+  metadef property inside a specific namespace.
+
+.. releasenotes/notes/add-metadef-property-delete-ebb999d92a588ad4.yaml @ b'9094e540b582073f62635c64d762b3a19db7a8e5'
+
+- Add ``image metadef property delete`` command to delete a
+  metadef property inside a specific namespace.
+
+.. releasenotes/notes/add-metadef-property-list-fe89ae8ff9780002.yaml @ b'5fb922e46953963ffbdadeef3e4854e7ae3c37b5'
+
+- Add ``image metadef property list`` command to list the
+  metadata definitions properties inside a specific namespace.
+
+.. releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml @ b'705ecef7a949ef6df0401fe98b66d1c8d96de1d6'
+
+- Add ``image metadef property set`` command to update a
+  metadef property inside a specific namespace.
+
+.. releasenotes/notes/add-metadef-property-show-8bf2ec421f74cb2d.yaml @ b'190f06a9633f2804a0aeff5d3effac8b7255d26c'
+
+- Add ``image metadef property show`` command to show details
+  about a metadef property inside a specific namespace.
+
+.. releasenotes/notes/migrate-volume-backend-commands-259e553e213c71b0.yaml @ b'39a084f91cd580be6adf46e8e752233112f6ec74'
+
+- Migrated following volume backends commands to SDK.
+  
+  * Capability Show
+  * Pool List
+
+.. releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml @ b'a3410cd4f785ec188973d85509448a320e882514'
+
+- The ``volume type create``, ``volume type set``, ``volume type list``
+  commands now accept four new options - ``--multiattach``, ``--cacheable``,
+  ``--replicated``, and ``--availability-zone`` - which are short cuts for
+  setting or filtering on the relevant properties on the volume type.
+
+.. releasenotes/notes/volume-type-list-properties-filter-8532f96d16733915.yaml @ b'67bec7785ce2e1af745a55d1838315dc6e849eaa'
+
+- The ``volume type list`` command now accepts a ``--property <key>=<value>``
+  option, allowing users to filter volume types by their extra spec
+  properties.
+
+
+.. _python-openstackclient_6.4.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/block-storage-x-manageable-list-long-option-a16a4641acfcf781.yaml @ b'8735b862c52daaafffd3c6d91c14be21891ac74b'
+
+- The ``--detailed`` option of the ``block storage volume manageable list``
+  and ``block storage snapshot manageable list`` commands has been deprecated
+  in favour of a ``--long`` option. These commands will no longer default to
+  detailed output by default.
+
+
+.. _python-openstackclient_6.4.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/migrate-resource-filter-commands-2a353edb965723d1.yaml @ b'ae10851a682adb1db7d3dca2794415437c2eaa79'
+
+- Migrated ``block storage resource filters list`` and
+  ``block storage resource filters show`` commands to SDK.
+
+
+.. _python-openstackclient_7.1.4:
+
+7.1.4
+=====
+
+.. _python-openstackclient_7.1.4_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2084580-cb1e8c47501e730c.yaml @ b'c6946f4743533449b5b8a3db2b1a8fe099b842da'
+
+- The ``quota set`` and ``limits show`` commands will now check for the
+  ``block-storage`` and ``block-store`` service types along with ``volume``,
+  ``volumev2`` and ``volumev3``.
+  
+  [Bug `2084580 <https://bugs.launchpad.net/python-openstackclient/+bug/2084580>`_]
+
+
+.. _python-openstackclient_7.1.0:
+
+7.1.0
+=====
+
+.. _python-openstackclient_7.1.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/aggregate-list-uuid-column-808a0d051006a5ef.yaml @ b'04ebe0853d1f59b8a18fcb8c8afffbc23dd0efc4'
+
+- The ``aggregate list`` command will now include the UUIDs of the aggregates
+  when the cloud supports it.
+
+
+.. _python-openstackclient_7.0.0:
+
+7.0.0
+=====
+
+.. _python-openstackclient_7.0.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-cluster-to-service-list-5eab3e828de7547e.yaml @ b'ca81b1acf05d87871ae2c672d7900dfb67d52ec0'
+
+- Added the ``Cluster`` and ``Backend State`` columns to
+  ``openstack volume service list`` command. Note that the
+  ``Cluster`` parameter is available since microversion 3.7
+  and ``Backend State`` parameter is available since
+  microversion 3.49.
+
+.. releasenotes/notes/add-image-metadef-object-property-show-4ab2c957451ea230.yaml @ b'2a90a6f07b52760b9442493d4c382d7e6ee1ced2'
+
+- Add ``image metadef object property show`` command which
+  shows a particular property inside metadef object.
+
+.. releasenotes/notes/add-image-metadef-resource-type-association-commands-4d373d7d8eca5d55.yaml @ b'276dbb6f5630cf96f260c8e347e85293b86a876f'
+
+- Added ``image metadef resource type association list``
+  to list resource type associations for the image service.
+  This is equivalent to the
+  ``md-namespace-resource-type-list`` command in glance.
+
+.. releasenotes/notes/add-image-metadef-resource-type-association-commands-4d373d7d8eca5d55.yaml @ b'276dbb6f5630cf96f260c8e347e85293b86a876f'
+
+- Added ``image metadef resource type association create``
+  to create a resource type association for the image service.
+  This is equivalent to the
+  ``md-resource-type-associate`` command in glance.
+
+.. releasenotes/notes/add-image-metadef-resource-type-association-commands-4d373d7d8eca5d55.yaml @ b'276dbb6f5630cf96f260c8e347e85293b86a876f'
+
+- Added ``image metadef resource type association delete``
+  to delete a resource type association for the image service.
+  This is equivalent to the
+  ``md-resource-type-deassociate`` command in glance.
+
+.. releasenotes/notes/add-port-numa-affinity-policy-socket-5a986b14033e0f6e.yaml @ b'966051cfe2e35c2a9c8a497bf5a6b626ba192b0c'
+
+- Add a new NUMA affinity policy option: "socket". That applies to any new
+  port (using ``port create``) or any existing port (using ``port set``).
+
+.. releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml @ b'4e94c415ed57c0d6366a7e49259e79fd6505ed6a'
+
+- Added support for unmanaging snapshots with the
+  ``openstack snapshot delete --remote`` command.
+
+.. releasenotes/notes/add-volume-manage-command-088890446d0e81c7.yaml @ b'cc7773f53bac61f602ce8ebc908878fd0914724c'
+
+- Add support for managing volumes with
+  ``openstack volume create --remote-source <key=val>
+  --host <host>`` command.
+
+.. releasenotes/notes/add-volume-unmanage-support-9b7139e5e948de77.yaml @ b'fdc2763ac2052f121e919a8513119e95ddd362d8'
+
+- Add support for unmanaging volumes with
+  ``openstack volume delete --remote <volume>`` command.
+
+.. releasenotes/notes/migrate-application-credential-to-sdk-c79d8dfc3c8e1d9f.yaml @ b'bef8a7a63098f903bcd2a9d42f2f37458602340f'
+
+- The following commands have been migrated to SDK:
+  
+  - ``application credential create``
+  - ``application credential delete``
+  - ``application credential list``
+  - ``application credential show``
+
+.. releasenotes/notes/migrate-role-assignment-to-sdk-e6e52bef467b4e4c.yaml @ b'de9d0f9e1b511c6aca7dea57f62331bb2638ef18'
+
+- Migrate ``role assignment`` commands from keystoneclient to SDK.
+
+.. releasenotes/notes/migrate-server-set-unset-to-sdk-ae32ebcced845b06.yaml @ b'bcaf2ab559e82d571cf46ed50aba60abf0b41637'
+
+- The ``server set`` and ``server unset`` commands have been migrated to SDK.
+
+.. releasenotes/notes/migrate-service-to-sdk-6ff62ebf7e41db7c.yaml @ b'717f242881ff58f1ddec994ffc68b82103ca7dab'
+
+- The following commands have been migrated to SDK:
+  
+  - ``service create``
+  - ``service delete``
+  - ``service set``
+  - ``service list``
+  - ``service show``
+
+.. releasenotes/notes/migrate-volume-attachment-commands-4309409bca1ca5d4.yaml @ b'9f30ee9af2f43d0754956454ab08cb0a10e847f4'
+
+- Migrated volume attachment commands to SDK.
+
+.. releasenotes/notes/quota-set-default-option-bc26d37dc150533b.yaml @ b'7d8baa87bba1003d61f08f0d20a4748513e1c45a'
+
+- The ``quota set`` command now supports a ``--default`` option. When
+  provided, this will allow you to set quotas for the default quota class
+  which is the only quota class supported by the Compute and Block Storage
+  services. This replaces the deprecated ``quota set --class`` option.
+
+
+.. _python-openstackclient_7.0.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/migrate-agent-commands-1c50ffcb75f91418.yaml @ b'0f07c97e847b8da75208bf7eedf6617d22ed65a5'
+
+- The ``compute agent *`` commands have been migrated to SDK.
+
+.. releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml @ b'7252a7a7817f57c2f38d0f5bf10739ff1fa58320'
+
+- The ``host set`` command has been migrated to SDK.
+
+.. releasenotes/notes/migrate-limits-show-f586c9762dfd7d0c.yaml @ b'9d394372823053e6a4038e14f81e14d1a32a6e3b'
+
+- The ``limits show`` command has been migrated to SDK.
+
+.. releasenotes/notes/migrate-server-evacuate-to-sdk-a0415988ef5451b2.yaml @ b'e6dc0f39c0891ea551867b77663a463b5f76987c'
+
+- The ``server evacuate`` command has been migrated to SDK.
+
+.. releasenotes/notes/network-quota-no-force-default-0975bdf15655070c.yaml @ b'da7eda66e96a72e7f51a9c6bebb4722503cc9662'
+
+- The ``openstack quota set`` command previously defaulted to ``--force`` behavior for network quotas. This behavior has now changed and the command now defaults to ``--no-force`` behavior. Users should specify the ``--force`` option if they wish to retain previous behavior.
+
+.. releasenotes/notes/remove-deprecated-quota-show-class-option-2109a6ff7ac18e80.yaml @ b'ba2d2358e614b8def13834c760ba551e973b33b1'
+
+- The ``--class`` options of the ``quota show`` command, which was deprecated
+  in 6.1.0 (Antelope), has now been removed in favour of the ``--default``
+  option. Quota classes were never fully implemented and the compute and
+  volume services only support a single ``default`` quota class while the
+  network service does not support quota classes at all.
+
+.. releasenotes/notes/rename-volume-set-retype-policy-6bacb7dd92f1ad82.yaml @ b'5a18f995a8ef31efb9ab324e2b5c9e572e75c2d1'
+
+- The ``volume set --retype-policy`` parameter has been renamed to
+  ``--migration-policy`` to better convey the correct meaning of the options
+  usage. The migration policy determines whether we are going to perform the
+  migration in the retype opearation or not and is not related to the actual
+  retype which just changes the volume type of the volume.
+
+
+.. _python-openstackclient_7.0.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/Router-flavor-accepts-name-or-id-e9cecafcddf81cb2.yaml @ b'2e7ba5e3dd8055e7eb2dcac9db1009db512a7fcc'
+
+- The ``router create --flavor-id`` parameter has been deprecated
+  in favour of the ``--flavor`` parameter, which accepts both
+  flavor names and flavor IDs.
+
+.. releasenotes/notes/fix-backup-incremental-d1c1e6886cf32256.yaml @ b'205bac3caf5ff983c60da0d171e51c1cc286024a'
+
+- Fixed issue with creating incremental volume backup.
+  Previously, ``incremental`` value was not passed in the
+  API request which is now included in the backup
+  create request.
+
+
+.. _python-openstackclient_7.4.0:
+
+7.4.0
+=====
+
+.. _python-openstackclient_7.4.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml @ b'426abbdc681d3f36f186fd685a3f1c0b6058f626'
+
+- Add ``--enable-uplink-status-propagation`` option and
+  ``--disable-uplink-status-propagation`` option to ``port update`` command.
+
+
+.. _python-openstackclient_7.3.0:
+
+7.3.0
+=====
+
+.. _python-openstackclient_7.3.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml @ b'47144103cabf11edb108ae80f700ea936bf50b30'
+
+- Add ``trusted`` attribute to the ``port create`` and ``port set`` commands.
+  It can be set to ``true`` with ``--trusted`` and to ``false`` with
+  ``--not-trusted`` CLI arguments passed to the ``port create`` and ``port
+  set`` commands``
+
+.. releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml @ b'34121473722b1e10ba9b64af9a3517dc2d6e422f'
+
+- Add ``qinq-vlan`` and ``no-qinq-vlan`` arguments to the ``network create``
+  command. It will enable/disable QinQ feature for the created network.
+  This new argument is mutually exclusive with the ``transparent-vlan`` - only
+  one of them can be set to ``True`` for the network.
+
+.. releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml @ b'5ef5cc9c82799290962b80aa663af0094572c903'
+
+- The ``server create`` command now supports a ``--no-security-group``
+  option. When provided, no security groups will be associated with ports
+  created and attached to the server during server creation. This does not
+  affect pre-created ports.
+
+.. releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml @ b'695d025f0028dae2715096b53629f1a00810d270'
+
+- Listing volume backups now shows the created_at column when
+  volume v3 API is used.
+
+
+.. _python-openstackclient_7.3.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml @ b'9c6df823e24fcb94823ebce9515973386cfed372'
+
+- The following commands have been migrated to SDK:
+  
+  - ``credential create``
+  - ``credential delete``
+  - ``credential list``
+  - ``credential set``
+  - ``credential show``
+
+.. releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml @ b'4c8290012d60b1b535594f95dbc5a9e18db721ea'
+
+- The following commands have been migrated to SDK:
+  
+  - ``region create``
+  - ``region list``
+  - ``region delete``
+  - ``region set``
+  - ``region show``
+
+.. releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml @ b'56baf50655cfe7948ca5e010b9377749066b6bf9'
+
+- The following commands have been migrated to SDK:
+  
+  - ``service provider create``
+  - ``service provider delete``
+  - ``service provider set``
+  - ``service provider list``
+  - ``service provider show``
+
+.. releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml @ b'769bf87d0a2a305d9ce53c91931f1c7016848053'
+
+- The following commands have been migrated to SDK:
+  
+  - ``trust create``
+  - ``trust list``
+  - ``trust delete``
+  - ``trust show``
+
+
+.. _python-openstackclient_7.3.0_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml @ b'03e2fdd1622d79b0199e349be042991f927f0414'
+
+- Fixed the output of ``volume backup restore`` command.
+
+.. releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml @ b'b6b18489b0b1b200c40e060f6c830103070d90f5'
+
+- Fixed the ``openstack volume backup show`` command
+  to show a backup by name.
+
+
+.. _python-openstackclient_7.2.1:
+
+7.2.1
+=====
+
+.. _python-openstackclient_7.2.1_Bug Fixes:
+
+Bug Fixes
+---------
+
+.. releasenotes/notes/bug-2084580-cb1e8c47501e730c.yaml @ b'7c6b47b451f30d1d3965358c515baae87955d7dc'
+
+- The ``quota set`` and ``limits show`` commands will now check for the
+  ``block-storage`` and ``block-store`` service types along with ``volume``,
+  ``volumev2`` and ``volumev3``.
+  
+  [Bug `2084580 <https://bugs.launchpad.net/python-openstackclient/+bug/2084580>`_]
+
+
+.. _python-openstackclient_7.2.0:
+
+7.2.0
+=====
+
+.. _python-openstackclient_7.2.0_New Features:
+
+New Features
+------------
+
+.. releasenotes/notes/add-port-list-status-option-f51da0aed0528a5d.yaml @ b'9c223696a0e3b45bcd8bcb0a8f81e3354ccea9c6'
+
+- Add ``--status`` option to ``port list`` command.
+  [Bug `1672680 <https://bugs.launchpad.net/python-openstackclient/+bug/1672680>`_]
+
+.. releasenotes/notes/add-remove-multiple-security-groups-2c0b2d599124c9c9.yaml @ b'ece30e8f703f918e391e934ecd2b201f211bfbfe'
+
+- The ``server add security group`` and ``server remove security group``
+  commands now accept multiple security groups.
+
+
+.. _python-openstackclient_7.2.0_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+.. releasenotes/notes/drop-python-38-9dcbd2b2b51f24f2.yaml @ b'7a92bc4abc4587c270fd86fdc44f231fdab7ab96'
+
+- Support for Python 3.8 has been dropped.
+
+.. releasenotes/notes/migrate-access-rule-to-sdk-923682b4c71fea8a.yaml @ b'415f68016ca783b5e44aa6b152c7136463467ab0'
+
+- The following commands have been migrated to SDK:
+  
+  - ``access rule list``
+  - ``access rule delete``
+  - ``access rule show``
+
diff -pruN 7.4.0-3/bindep.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/bindep.txt
--- 7.4.0-3/bindep.txt	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/bindep.txt	2025-07-07 22:41:56.000000000 +0000
@@ -8,3 +8,4 @@ libffi-dev [compile test platform:dpkg]
 libssl-dev [compile test platform:dpkg]
 python3-dev [compile test platform:dpkg]
 python3-devel [compile test platform:rpm]
+libpcre3-dev [test platform:dpkg]
diff -pruN 7.4.0-3/debian/AUTHORS 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/AUTHORS
--- 7.4.0-3/debian/AUTHORS	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/AUTHORS	1970-01-01 00:00:00.000000000 +0000
@@ -1,503 +0,0 @@
-Aaron Rosen <aaronorosen@gmail.com>
-Abhishek Chanda <abhishek@cloudscaling.com>
-Abhishek Raut <rauta@vmware.com>
-Adam Harwell <flux.adam@gmail.com>
-Adam Spiers <aspiers@suse.com>
-Adriano Fialho <dritec@gmail.com>
-Akihiro Motoki <amotoki@gmail.com>
-Akihiro Motoki <motoki@da.jp.nec.com>
-Alan Bishop <abishop@redhat.com>
-Alessandro Pilotti <ap@pilotti.it>
-Alessio Ababilov <aababilo@yahoo-inc.com>
-Alessio Ababilov <aababilov@griddynamics.com>
-Alex Gaynor <alex.gaynor@gmail.com>
-Alex Holden <alex@alexjonasholden.com>
-Alex Katz <akatz@akatz.tlv.csb>
-Alex Schultz <aschultz@mirantis.com>
-Alexander Gräb <alexander.graeb@secustack.com>
-Alexander Ignatov <aignatov@mirantis.com>
-Alfredo Moralejo <amoralej@redhat.com>
-Allain Legacy <Allain.legacy@windriver.com>
-Alvaro Lopez Garcia <aloga@ifca.unican.es>
-Amey Bhide <abhide@vmware.com>
-Andreas Florath <Andreas.Florath@telekom.de>
-Andreas Jaeger <aj@suse.com>
-Andreas Jaeger <aj@suse.de>
-Andrey Kurilin <akurilin@mirantis.com>
-Andrey Larionov <anlarionov@gmail.com>
-Anh Tran <anhtt@vn.fujitsu.com>
-Anindita Das <anindita.das@intel.com>
-Anita Kuno <anteaya@anteaya.info>
-Ankur Gupta <ankur.gupta@intel.com>
-Anne Gentle <agentle@cisco.com>
-Anton Frolov <af9740@att.com>
-Aradhana Singh <aradhana1.singh>
-Artem Goncharov <Artem.goncharov@gmail.com>
-Artem Goncharov <artem.goncharov@gmail.com>
-Artom Lifshitz <alifshit@redhat.com>
-Asha Saravanamohan <assarava@cisco.com>
-Ashish Singh <ashish.singh7@tcs.com>
-Atsushi SAKAI <sakaia@jp.fujitsu.com>
-Badhmapriya Boopalan <Badhmapriya.Boopalan@cognizant.com>
-Ben Andrews <andrewsben@gmail.com>
-Bence Romsics <bence.romsics@ericsson.com>
-Bence Romsics <bence.romsics@gmail.com>
-Benoît Knecht <benoit.knecht@fsfe.org>
-Bernard Cafarelli <bcafarel@redhat.com>
-Bharat Kunwar <bharat@stackhpc.com>
-Bhuvan Arumugam <bhuvan@apache.org>
-Bin Zhou <zhou.bin9@zte.com.cn>
-Boris Bobrov <bbobrov@mirantis.com>
-Boris Pavlovic <boris@pavlovic.me>
-Brad Behle <behle@us.ibm.com>
-Bram Verschueren <verschueren.bram@gmail.com>
-Brandon Palm <bapalm@us.ibm.com>
-Brian Haley <bhaley@redhat.com>
-Brian Haley <brian.haley@hpe.com>
-Brian Rosmaita <brian.rosmaita@rackspace.com>
-Brian Rosmaita <rosmaita.fossdev@gmail.com>
-Brianna Poulos <Brianna.Poulos@jhuapl.edu>
-Cao Xuan Hoang <hoangcx@vn.fujitsu.com>
-Carl Baldwin <carl@ecbaldwin.net>
-Carlos Goncalves <carlos.goncalves@neclab.eu>
-Carlos Konstanski <ckonstanski@pippiandcarlos.com>
-Cedric Brandily <zzelle@gmail.com>
-Chaozhe.Chen <chaozhe.chen@easystack.cn>
-Chen <dstbtgagt@foxmail.com>
-Chen Hanxiao <chenhx@certusnet.com.cn>
-Choe, Cheng-Dae <whitekid@gmail.com>
-Chris Johnson <wchrisjohnson@gmail.com>
-Christian Berendt <berendt@b1-systems.de>
-Christian Schneemann <schneemann@b1-systems.de>
-Chuck Short <chuck.short@canonical.com>
-Clark Boylan <clark.boylan@gmail.com>
-Colleen Murphy <colleen.murphy@suse.com>
-Colleen Murphy <colleen.murphy@suse.de>
-Colleen Murphy <colleen@gazlene.net>
-Colleen Murphy <colleen@puppetlabs.com>
-Colleen Murphy <comurphy@suse.com>
-Corey Bryant <corey.bryant@canonical.com>
-Cyril Roelandt <cyril.roelandt@enovance.com>
-Cyril Roelandt <cyril@redhat.com>
-Dag Stenstad <dag@stenstad.net>
-Daisuke Fujita <fuzita.daisuke@jp.fujitsu.com>
-Daniel Baumann <daniel.baumann@progress-linux.org>
-Daniel Bengtsson <dbengt@redhat.com>
-Daniel Gonzalez <daniel@gonzalez-nothnagel.de>
-Daniel Speichert <Daniel_Speichert@comcast.com>
-Daniel Speichert <daniel@speichert.pl>
-Daniel Strong <dstrong@glyx.co.uk>
-Dao Cong Tien <tiendc@vn.fujitsu.com>
-Davanum Srinivas <davanum@gmail.com>
-Dave Chen <wei.d.chen@intel.com>
-David Moreau Simard <dms@redhat.com>
-David Moreau Simard <dmsimard@iweb.com>
-David Rabel <rabel@b1-systems.de>
-David Rosales <darosale@us.ibm.com>
-Dean Troyer <dtroyer@gmail.com>
-Dina Belova <dbelova@mirantis.com>
-Dirk Mueller <dirk@dmllr.de>
-Dmitriy Rabotyagov <drabotyagov@vexxhost.com>
-Dmitriy Rabotyagov <noonedeadpunk@ya.ru>
-Dmitry Tantsur <dtantsur@protonmail.com>
-Dolph Mathews <dolph.mathews@gmail.com>
-Dongcan Ye <hellochosen@gmail.com>
-Doug Hellmann <doug.hellmann@dreamhost.com>
-Doug Hellmann <doug@doughellmann.com>
-Doug Wiegley <dwiegley@salesforce.com>
-Dougal Matthews <dougal@redhat.com>
-Einst Crazy <yu.changcai@99cloud.net>
-Elena Ezhova <eezhova@mirantis.com>
-Elod Illes <elod.illes@est.tech>
-Emilien Macchi <emilien@redhat.com>
-Eric Brown <browne@vmware.com>
-Eric Fried <openstack@fried.cc>
-Fan Zhang <zh.f@outlook.com>
-Fang Zhen <zhen.fang@easystack.cn>
-Fei Long Wang <flwang@catalyst.net.nz>
-Felix Yan <felixonmars@archlinux.org>
-Flavio Percoco <flaper87@gmail.com>
-Florent Flament <florent.flament-ext@cloudwatt.com>
-Gabriel Ramirez <gabrielramirez1109@gmail.com>
-Gage Hugo <gagehugo@gmail.com>
-Gary Kotton <gkotton@vmware.com>
-Georgina Shippey <georgina.shippey@bbc.co.uk>
-Ghanshyam Mann <gmann@ghanshyammann.com>
-Ghe Rivero <ghe.rivero@hp.com>
-Gilles Dubreuil <gilles@redhat.com>
-Glenn Van de Water <glenn.van_de_water@nuagenetworks.net>
-Guang Yee <guang.yee@hpe.com>
-Guang Yee <guang.yee@suse.com>
-Guojian Shao <guojian@unitedstack.com>
-Guoqiang Ding <dingguoqiang@cloudin.cn>
-Gábor Antal <antal@inf.u-szeged.hu>
-Ha Van Tu <tuhv@vn.fujitsu.com>
-Hang Yang <hangyang@verizonmedia.com>
-Hangdong Zhang <hdzhang@fiberhome.com>
-Harald Jensas <hjensas@redhat.com>
-Harry Rybacki <hrybacki@redhat.com>
-He Jie Xu <hejie.xu@intel.com>
-Henry Nash <henryn@linux.vnet.ibm.com>
-Hidekazu Nakamura <hid-nakamura@vf.jp.nec.com>
-Hideki Saito <saito@fgrep.org>
-Hieu LE <hieulq@vn.fujitsu.com>
-Hironori Shiina <shiina.hironori@jp.fujitsu.com>
-Hong Hui Xiao <honghui_xiao@yeah.net>
-Hongbin Lu <hongbin.lu@huawei.com>
-Hongbin Lu <hongbin034@gmail.com>
-Honza Pokorny <honza@redhat.com>
-Huan Xiong <huan.xiong@hxt-semitech.com>
-Huang Cheng <huang.cheng@h3c.com>
-Huanxuan Ao <huanxuan.ao@easystack.cn>
-Hugh Saunders <hugh@wherenow.org>
-Ian Wienand <iwienand@redhat.com>
-Igor Malinovskiy <u.glide@gmail.com>
-Igor_Bolotin <Igor_Bolotin@symantec.com>
-Igor_Bolotin <igor_bolotin@symantec.com>
-Ilya Persky <ipersky@yahoo-inc.com>
-Imtiaz Chowdhury <imtiaz.chowdhury@workday.com>
-Inessa Vasilevskaya <ivasilevskaya@mirantis.com>
-Iswarya_Vakati <v.iswarya@nectechnologies.in>
-Ivan Kolodyazhny <e0ne@e0ne.info>
-JP Parkin <jpparkin@ca.ibm.com>
-Jackie Yuan <yj2311@126.com>
-Jake Yip <jake.yip@unimelb.edu.au>
-James Denton <james.denton@rackspace.com>
-James E. Blair <jeblair@hp.com>
-James E. Blair <jeblair@redhat.com>
-James Page <james.page@ubuntu.com>
-Jamie Lennox <jamielennox@redhat.com>
-Jan Gutter <jan.gutter@netronome.com>
-Jas <singhj@us.ibm.com>
-Jaspreet Singh Rawel <jaspreetsinghrawel@gmail.com>
-Javier Pena <jpena@redhat.com>
-Jean-Philippe Evrard <jean-philippe@evrard.me>
-Jens Harbott (frickler) <j.harbott@x-ion.de>
-Jens Harbott <j.harbott@x-ion.de>
-Jens Rosenboom <j.rosenboom@x-ion.de>
-Jeremy Houser <jh629g@att.com>
-Jeremy Liu <liujiong@gohighsec.com>
-Jeremy Stanley <fungi@yuggoth.org>
-Jerry George <jerry@ca.ibm.com>
-Jim Rollenhagen <jim@jimrollenhagen.com>
-Jimmy McCrory <jimmy.mccrory@gmail.com>
-JingLiu <liu.jing5@zte.com.cn>
-Jirayut Nimsaeng <wingth@gmail.com>
-Joe Gordon <joe.gordon0@gmail.com>
-Joe Wigglesworth <wiggles@ca.ibm.com>
-Johannes Kulik <johannes.kulik@sap.com>
-John Dennis <jdennis@redhat.com>
-John Keenleyside <keenley@ca.ibm.com>
-Jordan Pittier <jordan.pittier@scality.com>
-Jose Castro Leon <jose.castro.leon@cern.ch>
-Josephine Seifert <josephine.seifert@secustack.com>
-Josh Kearney <josh.kearney@pistoncloud.com>
-Joshua Harlow <harlowja@yahoo-inc.com>
-Juan Antonio Osorio Robles <juan.osorio.robles@ericsson.com>
-Jude Cross <jucross@blizzard.com>
-Jude Job <judeopenstack@gmail.com>
-Julie Pichon <jpichon@redhat.com>
-Julien Danjou <julien@danjou.info>
-Justin A Wilson <justin.wilson@intel.com>
-KATO Tomoyuki <kato.tomoyuki@jp.fujitsu.com>
-Kailun Qin <kailun.qin@intel.com>
-KeithMnemonic <keith.berger@suse.com>
-Kelvin Lui <kelvinlittle@yahoo.com>
-Ken Thomas <krt@yahoo-inc.com>
-Kendall Nelson <kennelson11@gmail.com>
-Kenneth Chu <chukenne@ca.ibm.com>
-Kevin_Zheng <zhengzhenyu@huawei.com>
-Kristi Nikolla <knikolla@bu.edu>
-Kyrylo Romanenko <kromanenko@mirantis.com>
-LIU Yulong <i@liuyulong.me>
-Lajos Katona <lajos.katona@ericsson.com>
-Lance Bragstad <lbragstad@gmail.com>
-Lewis Denny <ldenny@redhat.com>
-Lin Yang <lin.a.yang@intel.com>
-Lingxian Kong <anlin.kong@gmail.com>
-LiuNanke <nanke.liu@easystack.cn>
-Lorin Hochstein <lorin@nimbisservices.com>
-Lu lei <lei.lu@easystack.cn>
-Léo GEORGEL <leo.georgel@osones.com>
-M V P Nitesh <m.nitesh@nectechnologies.in>
-Maari Tamm <tamm.maari@gmail.com>
-Madhu Mohan Nelemane <mmnelemane@suse.com>
-Major Hayden <major@mhtx.net>
-Manjeet Singh Bhatia <manjeet.s.bhatia@intel.com>
-Manuel Silveyra <silveyra@us.ibm.com>
-Marc Abramowitz <marc@marc-abramowitz.com>
-Marco Fargetta <marco.fargetta@ct.infn.it>
-Marcos Fermin Lobo <marcos.fermin.lobo@cern.ch>
-Marek Aufart <maufart@redhat.com>
-Marek Denis <marek.denis@cern.ch>
-Mark Vanderwiel <vanderwl@us.ibm.com>
-Martin Chlumsky <martin.chlumsky@gmail.com>
-Martin Schuppert <mschuppert@redhat.com>
-Masayuki Igawa <masayuki@igawa.io>
-Matt Fischer <matt@mattfischer.com>
-Matt Joyce <matt.joyce@cloudscaling.com>
-Matt Riedemann <mriedem.os@gmail.com>
-Matt Riedemann <mriedem@us.ibm.com>
-Matthew Treinish <mtreinish@kortar.org>
-Matthieu Huin <mhu@enovance.com>
-Michael Gugino <michael.gugino@walmart.com>
-Michael Johnson <johnsomor@gmail.com>
-Michael McCune <msm@redhat.com>
-Michal Arbet <michal.arbet@ultimum.io>
-Miguel Lavalle <miguel.lavalle@verizonmedia.com>
-Mike Fedosin <mfedosin@redhat.com>
-Mikhail Feoktistov <mfeoktistov@virtuozzo.com>
-Min Min Ren <rminmin@cn.ibm.com>
-Mohammed Naser <mnaser@vexxhost.com>
-Mohan Muppidi <mkumar2301@gmail.com>
-Monty Taylor <mordred@inaugust.com>
-Mouad Benchchaoui <m.benchchaoui@x-ion.de>
-Myeongchul Chae <cocahack@naver.com>
-Nakul Dahiwade <nakul.dahiwade@intel.com>
-Nam Nguyen Hoai <namnh@vn.fujitsu.com>
-Natal Ngétal <hobbestigrou@erakis.eu>
-Nathan Kinder <nkinder@redhat.com>
-Navid Pustchi <npustchi@gmail.com>
-Nguyen Phuong An <AnNP@vn.fujitsu.com>
-Nguyen Van Duc <ducnv@vn.fujitsu.com>
-NiallBunting <niall.bunting@hp.com>
-NiallBunting <niall.bunting@hpe.com>
-Nicolas Simonds <nic@metacloud.com>
-Nikita Gerasimov <nikita.gerasimov@oracle.com>
-Nir Magnezi <nmagnezi@redhat.com>
-Noam Angel <noama@mellanox.com>
-Nobuto Murata <nobuto.murata@canonical.com>
-Noorul Islam K M <noorul@noorul.com>
-Oleksii Chuprykov <ochuprykov@mirantis.com>
-Ondřej Nový <novy@ondrej.org>
-Ondřej Nový <ondrej.novy@firma.seznam.cz>
-Ondřej Nový <onovy@debian.org>
-OpenStack Release Bot <infra-root@openstack.org>
-Paul Belanger <paul.belanger@polybeacon.com>
-Paul Bourke <paul.bourke@oracle.com>
-Pavlo Shchelokovskyy <shchelokovskyy@gmail.com>
-Pedro Navarro <pednape@gmail.com>
-Pete Zaitcev <zaitcev@kotori.zaitcev.us>
-Petr Blaho <pblaho@redhat.com>
-Pierre Hanselmann <pierre.hanselmann@gmail.com>
-Pierre Prinetti <pierreprinetti@redhat.com>
-Pierre Riteau <pierre@stackhpc.com>
-Qiu Yu <qiuyu@ebaysf.com>
-Radoslaw Smigielski <radoslaw.smigielski@nokia.com>
-Radosław Piliszek <radoslaw.piliszek@gmail.com>
-Radu Mateescu <mateescu@ca.ibm.com>
-Rafael Weingärtner <rafael@apache.org>
-Rajasi Kulkarni <rajasikulkarni18@gmail.com>
-Ramaraja <ramaraja.r@hcl.com>
-Ramaraja Ramachandran <ramaraja.r@hcl.com>
-Reedip <reedip.banerjee@nectechnologies.in>
-Reedip <reedip14@gmail.com>
-Richard Theis <rtheis@us.ibm.com>
-Rikimaru Honjo <honjo.rikimaru@po.ntts.co.jp>
-Robert Francis <robefran@ca.ibm.com>
-Robin Cernin <rcernin@redhat.com>
-Rodolfo Alonso Hernandez <ralonsoh@redhat.com>
-Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
-Rodrigo Duarte <rodrigods@lsd.ufcg.edu.br>
-Rodrigo Duarte Sousa <rduartes@redhat.com>
-Rodrigo Duarte Sousa <rodrigods@lsd.ufcg.edu.br>
-Roger Luethi <rl@patchworkscience.org>
-Roxana Gherle <roxana.gherle@hp.com>
-Ruby Loo <rloo@oath.com>
-Rudolf Vriend <rudolf.vriend@sap.com>
-Rui Chen <chenrui.momo@gmail.com>
-Rui Yuan Dou <rydou@fiberhome.com>
-Rushi Agrawal <rushi.agr@gmail.com>
-Ryan Selden <ryanx.seldon@intel.com>
-SaiKiran <saikiranveeravarapu@gmail.com>
-Sakirnth Nagarasa <sakirnth@gmail.com>
-Sam Morrison <sorrison@gmail.com>
-SamYaple <sam@yaple.net>
-Sami MAKKI <mail@samimakki.fr>
-Samuel Pilla <sp516w@att.com>
-Samuel de Medeiros Queiroz <samuel@lsd.ufcg.edu.br>
-Samuel de Medeiros Queiroz <samueldmq@gmail.com>
-Sascha Peilicke <saschpe@gmx.de>
-Sascha Peilicke <speilicke@suse.com>
-Sean Dague <sean@dague.net>
-Sean McGinnis <sean.mcginnis@gmail.com>
-Sean Mooney <work@seanmooney.info>
-Sean Perry <sean.perry@hp.com>
-Sean Perry <sean.perry@hpe.com>
-Shane Wang <shane.wang@intel.com>
-Shashank Kumar Shankar <shashank.kumar.shankar@intel.com>
-Sheel Rana <ranasheel2000@gmail.com>
-ShogoAdachi <sho-adachi@xc.jp.nec.com>
-Shu Yingya <yingya.shu@easystack.cn>
-Simon Merrick <simonmerrick@catalyst.net.nz>
-Sindhu Devale <sindhu.devale@intel.com>
-Sirushti Murugesan <sirushti.murugesan@hp.com>
-Slawek Kaplonski <skaplons@redhat.com>
-SongmingYan <yan.songming@zte.com.cn>
-Stephen Finucane <sfinucan@redhat.com>
-Stephen Finucane <stephen.finucane@intel.com>
-Steve Martinelli <s.martinelli@gmail.com>
-Steve Martinelli <stevemar@ca.ibm.com>
-Steven Hardy <shardy@redhat.com>
-Stuart McLaren <stuart.mclaren@hp.com>
-Surya Seetharaman <suryaseetharaman.9@gmail.com>
-Sven Wegener <sven.wegener@inovex.de>
-Swapnil Kulkarni (coolsvap) <me@coolsvap.net>
-Sławek Kapłoński <slawek@kaplonski.pl>
-Takashi Kajinami <tkajinam@redhat.com>
-Tang Chen <chen.tang@easystack.cn>
-Tang Chen <tangchen@cn.fujitsu.com>
-Telles Nobrega <tenobreg@redhat.com>
-Terry Howe <terrylhowe@gmail.com>
-Terry Howe <thowe@hp.com>
-TerryHowe <terrylhowe@gmail.com>
-Thomas Goirand <thomas@goirand.fr>
-Thomas Goirand <zigo@debian.org>
-Tim Burke <tim.burke@gmail.com>
-Tom Cocozzello <tjcocozz@us.ibm.com>
-Tom Jose Kalapura <tomjosekal@gmail.com>
-Tom Stappaerts <tom.stappaerts@nuagenetworks.net>
-Tovin Seven <vinhnt@vn.fujitsu.com>
-Travis Tripp <travis.tripp@hpe.com>
-Trevor McCasland <TM2086@att.com>
-Tuan Do Anh <tuanda@vn.fujitsu.com>
-Tytus Kurek <tytus.kurek@canonical.com>
-Ukesh Kumar Vasudevan <ukeshkumar@gmail.com>
-Valery Tschopp <valery.tschopp@switch.ch>
-Vasyl Saienko <vsaienko@mirantis.com>
-Victor Silva <victsou@gmail.com>
-Vijendra Soni <vijendra.soni@cognizant.com>
-Vincent Legoll <vincent.legoll@idgrilles.fr>
-Vishakha Agarwal <agarwalvishakha18@gmail.com>
-Vladimir Eremin <yottatsa@yandex-team.ru>
-Vu Cong Tuan <tuanvc@vn.fujitsu.com>
-Wenran Xiao <xiaowenran@unitedstack.com>
-Wenzhi Yu <wenzhi_yu@163.com>
-Witold Bedyk <witold.bedyk@est.fujitsu.com>
-Xi Yang <yang.xi@99cloud.net>
-Xiaoyang Zhang <xiaoyang.zhang@easystack.cn>
-YAMAMOTO Takashi <yamamoto@midokura.com>
-Yan Xing'an <yanxingan@cmss.chinamobile.com>
-Yang Hongyang <hongyang.yang@easystack.cn>
-Yang Youseok <ileixe@gmail.com>
-Yejia Xu <yejia@unitedstack.com>
-Yi Zhao <zhaoyi@cmss.chinamobile.com>
-Yongli He <yongli.he@intel.com>
-YuehuiLei <leiyuehui@inspur.com>
-Yunpeng Li <yunpeng.li@live.cn>
-Zane Bitter <zbitter@redhat.com>
-ZhaoBo <zhaobo6@huawei.com>
-Zhaokun Fu <fuzk@inspur.com>
-Zhenguo Niu <Niu.ZGlinux@gmail.com>
-ZhongShengping <chdzsp@163.com>
-Zhou Zhihong <zhouzhihong@cmss.chinamobile.com>
-adrian-turjak <adriant@catalyst.net.nz>
-asarfaty <asarfaty@vmware.com>
-blue55 <yllan@fiberhome.com>
-caoyuan <cao.yuan@99cloud.net>
-chengkunye <chengkun@unitedstack.com>
-chenxing <chason.chan@foxmail.com>
-chenying <ying.chen@huawei.com>
-daizhiyong <zhiyong.dai@easystack.cn>
-dongwenshuai <dong.wenshuai@zte.com.cn>
-gecong1973 <ge.cong@zte.com.cn>
-gengchc2 <geng.changcai2@zte.com.cn>
-guang-yee <guang.yee@hpe.com>
-guangpei.liu <guangpei.liu@easystack.cn>
-guiyanxing <guiyanxing@cmss.chinamobile.com>
-gustavo panizzo <gfa@zumbi.com.ar>
-gustavo panizzo <gpanizzo@exo.com.ar>
-gvrangan <venkatrangang@hcl.com>
-hackertron <jayadityagupta11@gmail.com>
-heha <zhanghanqun@unitedstack.com>
-henriquetruta <henrique@lsd.ufcg.edu.br>
-huangshan <huangshan@fiberhome.com>
-huangtianhua <huangtianhua@huawei.com>
-jay <jayadityagupta11@gmail.com>
-jeckxie <xiexiaozhe@inspur.com>
-ji-xuepeng <ji.xuepeng@zte.com.cn>
-jiahui.qiang <jiahui.qiang@easystack.cn>
-jiangpch <jiangpengcheng@navercorp.com>
-jiaxi <jiaxi@unitedstack.com>
-jichenjc <jichenjc@cn.ibm.com>
-jqjiang.1@gmail.com <jqjiang.1@gmail.com>
-judy-yu <yujie@cmss.chinamobile.com>
-kafka <guowang@unitedstack.com>
-licanwei <li.canwei2@zte.com.cn>
-lihaijing <lihaijing@fiberhome.com>
-likui <likui@yovole.com>
-lin-hua-cheng <os.lcheng@gmail.com>
-lingyongxu <lyxu@fiberhome.com>
-liujunpeng <liujunpeng@inspur.com>
-liusheng <liusheng@huawei.com>
-liuyamin <liuyamin@fiberhome.com>
-liyifeng <307419146@qq.com>
-liyingjun <liyingjun1988@gmail.com>
-lrqrun <lrqrun@gmail.com>
-lvjiawei <lvjiawei@cmss.chinamobile.com>
-lvxianguo <lvxianguo@inspur.com>
-maaoyu <maaoyu@inspur.com>
-mb711d <mb711d@att.com>
-melanie witt <melwittt@gmail.com>
-melissaml <ma.lei@99cloud.net>
-nidhimittalhada <nidhimittal19@gmail.com>
-npraveen35 <npraveen35@gmail.com>
-okozachenko <okozachenko@vexxhost.com>
-pedh <hcn518@gmail.com>
-pedro <phpm13@gmail.com>
-pengyuesheng <pengyuesheng@gohighsec.com>
-phil-hopkins-a <phil.hopkins@rackspace.com>
-qinchunhua <qin.chunhua@zte.com.cn>
-qingszhao <zhao.daqing@99cloud.net>
-qtang <qtang@vmware.com>
-rabi <ramishra@redhat.com>
-reedip <reedip.banerjee@nectechnologies.in>
-root <ranasheel2000@gmail.com>
-sharat.sharma <sharat.sharma@nectechnologies.in>
-shizhihui <zhihui.shi@easystack.cn>
-songminglong <songminglong@cmss.chinamobile.com>
-songwenping <songwenping@inspur.com>
-sonu.kumar <sonu.kumar@nectechnologies.in>
-sunjia <sunjia@inspur.com>
-sunyajing <yajing.sun@easystack.cn>
-tanlin <lin.tan@intel.com>
-tengqm <tengqim@cn.ibm.com>
-tianhui <tianhui@awcloud.com>
-timothy-symanczyk <timothy_symanczyk@symantec.com>
-ting wang <bx_wang@outlook.com>
-ting.wang <ting.wang@easystack.cn>
-venkata anil <anilvenkata@redhat.com>
-venkatamahesh <venkatamaheshkotha@gmail.com>
-wanghong <w.wanghong@huawei.com>
-wangxiyuan <wangxiyuan@huawei.com>
-wangzihao <wangzihao@yovole.com>
-whoami-rajat <rajatdhasmana@gmail.com>
-wingwj <wingwj@gmail.com>
-wu.chunyang <wu.chunyang@99cloud.net>
-wu.chunyang <wuchunyang@yovole.com>
-wu.shiming <wushiming@yovole.com>
-wuyuting <wytdahu@gmail.com>
-xiexs <xiexs@cn.fujitsu.com>
-yang wang <wangy@rc.inesa.com>
-yangweiwei <yangweiwei@cmss.chinamobile.com>
-yangxi <yang.xi@99cloud.net>
-yanpuqing <yanpq@awcloud.com>
-ycx <yanpq@awcloud.com>
-yfzhao <dsware@126.com>
-youngho choi <0505zxc@gmail.com>
-yushangbin <yushb@gohighsec.com>
-zhang.lei <zhang.lei@99cloud.net>
-zhang.xiuhua <zhang.xiuhua@99cloud.net>
-zhangbailin <zhangbailin@inspur.com>
-zhangboye <zhangboye@inspur.com>
-zhanghongtao <zhanghongtao0826@126.com>
-zheng yin <yin.zheng@easystack.cn>
-zhengsenyan <zhengsy_sean@126.com>
-zhiyong.dai <zhiyong.dai@easystack.cn>
-zhiyuan_cai <luckyvega.g@gmail.com>
-zhouhenglc <zhouhenglc@inspur.com>
-zhouqi <qi.zhou@easystack.cn>
-zhu.boxiang <zhu.boxiang@99cloud.net>
-zhufl <zhu.fanglei@zte.com.cn>
-zhurong <aaronzhu1121@gmail.com>
-Édouard Thuleau <ethuleau@juniper.net>
diff -pruN 7.4.0-3/debian/changelog 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/changelog
--- 7.4.0-3/debian/changelog	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/changelog	2025-08-05 16:47:42.000000000 +0000
@@ -1,312 +1,245 @@
-python-openstackclient (7.4.0-3) unstable; urgency=medium
+python-openstackclient (8.1.0+git2025070715.9d3a956a-0ubuntu2) questing; urgency=medium
 
-  * Re-upload.
+  * d/p/fix-pyproject-auto-discovery.patch: Add patch to discover submodules at
+    build time (ie, openstackclient-common, etc.). (LP: #2119562)
+  * d/control: Add pybuild-plugin-pyproject to Build-Depends.
 
- -- Thomas Goirand <zigo@debian.org>  Sat, 29 Mar 2025 10:27:26 +0100
+ -- Myles Penner <myles.penner@canonical.com>  Tue, 05 Aug 2025 09:47:42 -0700
 
-python-openstackclient (7.4.0-2) unstable; urgency=medium
+python-openstackclient (8.1.0+git2025070715.9d3a956a-0ubuntu1) questing; urgency=medium
 
-  * d/watch: switch to version=4 and mode=git.
-  * Uploading to unstable.
-
- -- Thomas Goirand <zigo@debian.org>  Fri, 28 Mar 2025 12:53:08 +0100
-
-python-openstackclient (7.4.0-1) experimental; urgency=medium
-
-  * New upstream release.
-  * Fixed (build-)depends for this release.
-
- -- Thomas Goirand <zigo@debian.org>  Mon, 03 Mar 2025 09:55:34 +0100
-
-python-openstackclient (6.6.0-6) unstable; urgency=medium
-
-  * Removed python3-saharaclient from build-depends.
-
- -- Thomas Goirand <zigo@debian.org>  Tue, 14 Jan 2025 08:38:19 +0100
-
-python-openstackclient (6.6.0-5) unstable; urgency=medium
-
-  * Add missing python3-simplejson (build-)depends (Closes: #1082696).
-
- -- Thomas Goirand <zigo@debian.org>  Wed, 25 Sep 2024 09:38:17 +0200
-
-python-openstackclient (6.6.0-4) unstable; urgency=medium
-
-  * Removed extraneous dependency on python3-mock (Closes: #1071714).
-
- -- Thomas Goirand <zigo@debian.org>  Sun, 02 Jun 2024 12:54:26 +0200
-
-python-openstackclient (6.6.0-3) unstable; urgency=medium
-
-  * Removed python3-karborclient from build-depends.
-
- -- Thomas Goirand <zigo@debian.org>  Thu, 09 May 2024 14:26:37 +0200
-
-python-openstackclient (6.6.0-2) unstable; urgency=medium
-
-  * Uploading to unstable.
-
- -- Thomas Goirand <zigo@debian.org>  Sun, 07 Apr 2024 23:06:56 +0200
-
-python-openstackclient (6.6.0-1) experimental; urgency=medium
-
-  * New upstream release.
-  * Removed python3-muranoclient from build-depends.
-
- -- Thomas Goirand <zigo@debian.org>  Tue, 19 Mar 2024 08:05:09 +0100
-
-python-openstackclient (6.5.0-1) experimental; urgency=medium
-
-  * New upstream release.
-  * Fixed (build-)depends for this release.
-
- -- Thomas Goirand <zigo@debian.org>  Fri, 01 Mar 2024 22:10:52 +0100
-
-python-openstackclient (6.3.0-3) unstable; urgency=medium
-
-  * Blacklist tests.unit.common.test_module.TestModuleList (Closes: #1058097).
-
- -- Thomas Goirand <zigo@debian.org>  Tue, 12 Dec 2023 16:22:02 +0100
-
-python-openstackclient (6.3.0-2) unstable; urgency=medium
-
-  * Uploading to unstable.
-
- -- Thomas Goirand <zigo@debian.org>  Sun, 08 Oct 2023 18:53:10 +0200
-
-python-openstackclient (6.3.0-1) experimental; urgency=medium
-
-  * New upstream release.
-  * Fixed (build-)depends for this release.
-
- -- Thomas Goirand <zigo@debian.org>  Sun, 17 Sep 2023 12:43:02 +0200
+  [ Guillaume Boutry ]
+  * d/gbp.conf, .launchpad.yaml: Sync from cloud-archive-tools for
+    flamingo.
 
-python-openstackclient (6.2.0-4) unstable; urgency=medium
+  [ Myles Penner ]
+  * New upstream release for OpenStack Flamingo. (LP: #2116155)
+  * d/control: Align (Build-)Depends with upstream.
+  * d/rules: Include PBR version.
+  * d/s/options: Ignore .launchpad.yaml when generating diffs.
 
-  * Cleans better (Closes: #1048950).
+ -- Myles Penner <myles.penner@canonical.com>  Mon, 14 Jul 2025 15:11:11 -0700
 
- -- Thomas Goirand <zigo@debian.org>  Tue, 22 Aug 2023 12:53:00 +0200
+python-openstackclient (7.4.0-0ubuntu1) plucky; urgency=medium
 
-python-openstackclient (6.2.0-3) unstable; urgency=medium
+  * New upstream release for OpenStack Epoxy.
 
-  * Add AUTHORS in the doc folder (Closes: #990337).
+ -- James Page <james.page@ubuntu.com>  Thu, 27 Feb 2025 12:47:04 +0000
 
- -- Thomas Goirand <zigo@debian.org>  Fri, 11 Aug 2023 12:20:22 +0200
+python-openstackclient (7.2.1-0ubuntu1) plucky; urgency=medium
 
-python-openstackclient (6.2.0-2) unstable; urgency=medium
+  * d/gbp.conf, .launchpad.yaml: Sync from cloud-archive-tools for
+    epoxy.
+  * New upstream release for OpenStack Epoxy.
+  * d/control: Drop dependencies that are no longer required.
 
-  * Uploading to unstable.
-
- -- Thomas Goirand <zigo@debian.org>  Tue, 20 Jun 2023 10:49:20 +0200
-
-python-openstackclient (6.2.0-1) experimental; urgency=medium
+ -- James Page <james.page@ubuntu.com>  Fri, 17 Jan 2025 09:23:53 +0000
 
-  * New upstream release.
+python-openstackclient (7.1.2-0ubuntu1) oracular; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Fri, 10 Mar 2023 08:46:33 +0100
+  * d/gbp.conf: upstream-branch -> upstream-dalmatian.
+  * New upstream release for OpenStack Dalmatian.
 
-python-openstackclient (6.1.0-1) experimental; urgency=medium
+ -- James Page <james.page@ubuntu.com>  Tue, 24 Sep 2024 16:33:01 +0100
 
-  * New upstream release.
-  * Fixed (build-)depends for this release, removing versions satisfied in
-    Bookworm.
+python-openstackclient (7.0.0-0ubuntu1) oracular; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Fri, 24 Feb 2023 12:13:52 +0100
+  * New upstream release. 
+  * d/control: Align (Build-)Depends with upstream.
+  * d/p/*: Drop, included in release.
 
-python-openstackclient (6.0.0-3) unstable; urgency=medium
+ -- James Page <james.page@ubuntu.com>  Wed, 07 Aug 2024 14:55:07 +0100
 
-  * Remove python3-congressclient build-depends.
+python-openstackclient (6.6.0-0ubuntu2) noble; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Thu, 29 Dec 2022 18:29:51 +0100
+  * d/p/lp-2002687-*: Add support for managing multiple gateways and
+    BFD/ECMP options (LP: #2060656).
 
-python-openstackclient (6.0.0-2) unstable; urgency=medium
+ -- Frode Nordahl <fnordahl@ubuntu.com>  Tue, 09 Apr 2024 10:58:28 +0100
 
-  * Uploading to unstable.
+python-openstackclient (6.6.0-0ubuntu1) noble; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Fri, 23 Sep 2022 17:33:28 +0200
-
-python-openstackclient (6.0.0-1) experimental; urgency=medium
-
-  * New upstream release.
-
- -- Thomas Goirand <zigo@debian.org>  Mon, 05 Sep 2022 09:10:04 +0200
+  [ Corey Bryant ]
+  * d/gbp.conf, .launchpad.yaml: Sync from cloud-archive-tools for
+    caracal.
 
-python-openstackclient (5.8.0-2) unstable; urgency=medium
+  [ James Page ]
+  * New upstream release for OpenStack Caracal.
+  * d/rules,exclude-list.txt: Skip test that failures due to patching
+    under Python 3.12.
 
-  * Uploading to unstable.
+ -- James Page <james.page@ubuntu.com>  Mon, 08 Apr 2024 11:30:44 +0100
 
- -- Thomas Goirand <zigo@debian.org>  Fri, 25 Mar 2022 12:10:33 +0100
+python-openstackclient (6.3.0-0ubuntu1) mantic; urgency=medium
 
-python-openstackclient (5.8.0-1) experimental; urgency=medium
+  * d/gbp.conf, .launchpad.yaml: Sync from cloud-archive-tools for
+    bobcat.
+  * New upstream release for OpenStack Bobcat.
+  * d/control: Align (Build-)Depends with upstream.
 
-  * New upstream release.
-  * Fixed (build-)depends for this release.
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 26 Sep 2023 14:34:23 -0400
 
- -- Thomas Goirand <zigo@debian.org>  Wed, 09 Mar 2022 22:47:47 +0100
+python-openstackclient (6.2.0-0ubuntu1) lunar; urgency=medium
 
-python-openstackclient (5.7.0-1) experimental; urgency=medium
+  * New upstream release for OpenStack Antelope.
 
-  * New upstream release.
-  * Add autopkgtest.
-  * Run all tests.
+ -- Corey Bryant <corey.bryant@canonical.com>  Thu, 23 Mar 2023 14:09:57 -0400
 
- -- Thomas Goirand <zigo@debian.org>  Sat, 26 Feb 2022 23:26:46 +0100
+python-openstackclient (6.1.0-0ubuntu1) lunar; urgency=medium
 
-python-openstackclient (5.6.0-2) unstable; urgency=medium
+  * New upstream release for OpenStack Antelope.
+  * d/control: Align (Build-)Depends with upstream.
 
-  * Uploading to unstable.
+ -- Corey Bryant <corey.bryant@canonical.com>  Fri, 24 Feb 2023 16:18:34 -0500
 
- -- Thomas Goirand <zigo@debian.org>  Wed, 29 Sep 2021 20:50:32 +0200
+python-openstackclient (6.0.0-0ubuntu1) kinetic; urgency=medium
 
-python-openstackclient (5.6.0-1) experimental; urgency=medium
+  * New upstream release for OpenStack Zed.
+  * d/control: Bump debhelper compat to 13.
+  * d/control: Update standards version to 4.6.1.
 
-  * New upstream release.
-  * Added myself in copyright and uploaders.
-  * Added versioned depends for openstacksdk >= 0.56.0.
+ -- Corey Bryant <corey.bryant@canonical.com>  Thu, 08 Sep 2022 18:25:53 -0400
 
- -- Sakirnth Nagarasa <sakirnth@gmail.com>  Thu, 02 Sep 2021 23:20:04 +0200
+python-openstackclient (5.8.0-0ubuntu1) jammy; urgency=medium
 
-python-openstackclient (5.5.0-2) unstable; urgency=medium
+  * New upstream release for OpenStack Yoga.
+  * d/control: Bump minimum version of openstacksdk.
 
-  * Add python3-cloudkittyclient and python3-manilaclient to build-depends, so
-    they can be included in the bash-completion script.
-  * Add Recommends: python-openstackclient-doc (Closes: #991954).
-  * Upload to unstable.
+ -- James Page <james.page@ubuntu.com>  Mon, 04 Apr 2022 14:41:18 +0100
 
- -- Thomas Goirand <zigo@debian.org>  Mon, 16 Aug 2021 11:45:15 +0200
+python-openstackclient (5.7.0-0ubuntu1) jammy; urgency=medium
 
-python-openstackclient (5.5.0-1) experimental; urgency=medium
+  * New upstream release for OpenStack Yoga.
 
-  * New upstream release.
-  * Debhelper 11.
-  * Removed (build-)depends versions when satisfied in Bullseye.
-  * Fixed (build-)depends for this release.
+ -- Chris MacNaughton <chris.macnaughton@ubuntu.com>  Wed, 01 Dec 2021 07:51:45 +0000
 
- -- Thomas Goirand <zigo@debian.org>  Mon, 22 Mar 2021 08:49:07 +0100
+python-openstackclient (5.6.0-0ubuntu2) jammy; urgency=medium
 
-python-openstackclient (5.4.0-3) unstable; urgency=medium
+  * d/control: Drop python3-crypto from (Build-)Depends.
 
-  * Removed python3-crypto from (build-)depends (Closes: #971307).
+ -- James Page <james.page@ubuntu.com>  Fri, 12 Nov 2021 09:39:35 +0000
 
- -- Thomas Goirand <zigo@debian.org>  Sun, 22 Nov 2020 12:18:50 +0100
+python-openstackclient (5.6.0-0ubuntu1) impish; urgency=medium
 
-python-openstackclient (5.4.0-2) unstable; urgency=medium
+  * New upstream release for OpenStack Xena.
+  * d/control: Align (Build-)Depends with upstream.
 
-  * Uploading to unstable.
-  * Fixed debian/watch.
-  * Add a debian/salsa-ci.yml.
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 07 Sep 2021 14:06:22 -0400
 
- -- Thomas Goirand <zigo@debian.org>  Fri, 16 Oct 2020 17:47:34 +0200
+python-openstackclient (5.5.0-0ubuntu1) hirsute; urgency=medium
 
-python-openstackclient (5.4.0-1) experimental; urgency=medium
+  * New upstream release for OpenStack Wallaby.
+  * d/control: Align (Build-)Depends with upstream.
 
-  * New upstream release.
-  * Re-added python3-mock as build-depends.
+ -- Corey Bryant <corey.bryant@canonical.com>  Mon, 12 Apr 2021 15:39:36 -0400
 
- -- Thomas Goirand <zigo@debian.org>  Mon, 05 Oct 2020 10:29:21 +0200
+python-openstackclient (5.4.0-0ubuntu1) groovy; urgency=medium
 
-python-openstackclient (5.3.1-1) experimental; urgency=medium
+  * d/control: Update VCS paths for move to lp:~ubuntu-openstack-dev.
+  * New upstream release for OpenStack Victoria.
 
-  * New upstream release.
-  * Fixed (build-)depends for this release.
+ -- Chris MacNaughton <chris.macnaughton@ubuntu.com>  Fri, 09 Oct 2020 06:33:57 +0000
 
- -- Thomas Goirand <zigo@debian.org>  Sun, 13 Sep 2020 16:05:39 +0200
+python-openstackclient (5.3.1-0ubuntu1) groovy; urgency=medium
 
-python-openstackclient (5.2.1-1) unstable; urgency=medium
+  * New upstream release for OpenStack Victoria.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/control, d/rules: Switch to debhelper compat 12 and pybuild.
+  * d/control: Update Standards-Version to 4.5.0.
 
-  * New upstream release.
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 28 Jul 2020 20:33:41 -0400
 
- -- Thomas Goirand <zigo@debian.org>  Sat, 20 Jun 2020 19:03:52 +0200
+python-openstackclient (5.2.0-0ubuntu1) focal; urgency=medium
 
-python-openstackclient (5.2.0-2) unstable; urgency=medium
+  * New upstream release for OpenStack Ussuri.
+  * d/control: Align (Build-)Depends with upstream.
 
-  * Uploading to unstable.
+ -- James Page <james.page@ubuntu.com>  Mon, 30 Mar 2020 15:59:21 +0100
 
- -- Thomas Goirand <zigo@debian.org>  Sat, 09 May 2020 00:07:08 +0200
+python-openstackclient (4.0.0-0ubuntu2) focal; urgency=medium
 
-python-openstackclient (5.2.0-1) experimental; urgency=medium
+  * d/control: Drop python3-keyring as it is no longer used (LP: #1861268).
 
-  * New upstream release.
-  * Fixed (build-)depends for this release.
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 04 Feb 2020 13:28:26 -0500
 
- -- Thomas Goirand <zigo@debian.org>  Sun, 12 Apr 2020 18:57:17 +0200
+python-openstackclient (4.0.0-0ubuntu1) eoan; urgency=medium
 
-python-openstackclient (4.0.0-2) unstable; urgency=medium
+  * New upstream release for OpenStack Train.
+  * d/control: Align (Build-)Depends with upstream.
 
-  [ Ondřej Nový ]
-  * Run wrap-and-sort -bastk.
-  * Bump Standards-Version to 4.4.1.
+ -- Corey Bryant <corey.bryant@canonical.com>  Wed, 25 Sep 2019 14:23:09 -0400
 
-  [ Thomas Goirand ]
-  * Uploading to unstable.
+python-openstackclient (3.19.0-0ubuntu2) eoan; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Mon, 21 Oct 2019 09:28:33 +0200
+  * d/tests/control: Drop Python 2 autopkgtest now that we no longer
+    have a Python 2 binary package.
 
-python-openstackclient (4.0.0-1) experimental; urgency=medium
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 17 Sep 2019 15:43:12 +0200
 
-  [ Ondřej Nový ]
-  * d/control: Add trailing tilde to min version depend to allow
-    backports.
-  * Bump Standards-Version to 4.4.0.
+python-openstackclient (3.19.0-0ubuntu1) eoan; urgency=medium
 
-  [ Thomas Goirand ]
-  * New upstream release.
-  * Fixed (build-)depends for this release.
+  * New upstream release for OpenStack Train.
+  * d/control: Align (Build-)Depends with upstream.
 
- -- Thomas Goirand <zigo@debian.org>  Tue, 17 Sep 2019 10:26:52 +0200
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 30 Jul 2019 15:33:27 -0400
 
-python-openstackclient (3.18.0-2) unstable; urgency=medium
+python-openstackclient (3.18.0-0ubuntu2) eoan; urgency=medium
 
-  [ Ondřej Nový ]
-  * Use debhelper-compat instead of debian/compat.
+  * d/control: Drop BDI's on python-* packages.
+  * d/control: Drop python-openstackclient binary package.
+  * d/*.postinst,prerm,postrm: Drop, alternatives no longer needed.
+  * d/rules: Tweak to stop build and install of Python 2 parts.
 
-  [ Thomas Goirand ]
-  * Uploading to unstable.
+ -- Sahid Orentino Ferdjaoui <sahid.ferdjaoui@canonical.com>  Mon, 15 Jul 2019 10:03:02 +0100
 
- -- Thomas Goirand <zigo@debian.org>  Thu, 18 Jul 2019 23:46:31 +0200
+python-openstackclient (3.18.0-0ubuntu1) disco; urgency=medium
 
-python-openstackclient (3.18.0-1) experimental; urgency=medium
+  * New upstream release for OpenStack Stein.
+  * d/control: Align (Build-)Depends with upstream.
 
-  * New upstream release.
-  * Removed Python 2 support.
+ -- Corey Bryant <corey.bryant@canonical.com>  Mon, 11 Mar 2019 16:37:25 -0400
 
- -- Thomas Goirand <zigo@debian.org>  Mon, 25 Mar 2019 22:49:35 +0100
+python-openstackclient (3.17.0-0ubuntu1) disco; urgency=medium
 
-python-openstackclient (3.16.2-1) unstable; urgency=medium
+  * New upstream release for OpenStack Stein.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/p/drop-sphinxcontrib-apidoc.patch: Droped. No longer needed.
 
-  [ Ondřej Nový ]
-  * Running wrap-and-sort -bast
-  * Use 'python3 -m sphinx' instead of sphinx-build for building docs
+ -- Corey Bryant <corey.bryant@canonical.com>  Wed, 30 Jan 2019 10:15:56 -0500
 
-  [ Thomas Goirand ]
-  * New upstream point release.
+python-openstackclient (3.16.1-0ubuntu1) cosmic; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Thu, 21 Feb 2019 09:20:30 +0100
+  * New stable point release for OpenStack Rocky.
 
-python-openstackclient (3.16.0-3) unstable; urgency=high
+ -- Corey Bryant <corey.bryant@canonical.com>  Thu, 04 Oct 2018 12:33:47 -0400
 
-  * Remove the test suite which is doing apt-get, and that isn't advised.
+python-openstackclient (3.16.0-0ubuntu1) cosmic; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Wed, 12 Sep 2018 09:36:40 +0200
+  * New upstream release for OpenStack Rocky.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/p/drop-sphinxcontrib-apidoc.patch: Drop sphinxcontrib.apidoc extension
+    until package is available.
 
-python-openstackclient (3.16.0-2) unstable; urgency=medium
+ -- Corey Bryant <corey.bryant@canonical.com>  Wed, 01 Aug 2018 15:27:19 -0400
 
-  * Uploading to unstable.
+python-openstackclient (3.15.0-0ubuntu2) cosmic; urgency=medium
 
- -- Thomas Goirand <zigo@debian.org>  Wed, 05 Sep 2018 09:53:53 +0200
+  * d/tests/*: Switch to our standard client dep8 tests instead of using
+    openstack-deploy.
 
-python-openstackclient (3.16.0-1) experimental; urgency=medium
+ -- Corey Bryant <corey.bryant@canonical.com>  Wed, 20 Jun 2018 08:49:23 -0400
 
-  [ Ondřej Nový ]
-  * d/control: Use team+openstack@tracker.debian.org as maintainer
+python-openstackclient (3.15.0-0ubuntu1) cosmic; urgency=low
 
-  [ Thomas Goirand ]
+  * Merge from Debian unstable.  Remaining changes:
+    - d/gbp.conf: Retain for gbp and pristine-tar config.
+    - d/control: Enable autopkgtest-pkg-python testsuite.
+    - d/watch: Get tarball from tarballs.openstack.org.
   * New upstream release.
-  * Fixed (build-)depends for this release.
-  * Building sphinx doc with Python 3.
-  * Remove fix-output-encoding.patch applied upstream.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/p/fix-output-encoding.patch: Dropped. Fixed in upstream release.
 
- -- Thomas Goirand <zigo@debian.org>  Wed, 22 Aug 2018 15:31:26 +0200
+ -- Corey Bryant <corey.bryant@canonical.com>  Tue, 12 Jun 2018 11:16:58 -0400
 
 python-openstackclient (3.14.2-1) unstable; urgency=medium
 
@@ -363,6 +296,24 @@ python-openstackclient (3.14.0-1) experi
 
  -- Thomas Goirand <zigo@debian.org>  Tue, 13 Feb 2018 22:51:34 +0000
 
+python-openstackclient (3.14.0-0ubuntu1) bionic; urgency=medium
+
+  * New upstream release.
+  * d/control: Align (Build-)Depends with upstream.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Mon, 12 Feb 2018 09:30:43 -0500
+
+python-openstackclient (3.13.0-0ubuntu1) bionic; urgency=medium
+
+  * New upstream release.
+  * d/*: wrap-and-sort -bast.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/control: Update Standards-Version to 4.1.2.
+  * d/control: Bump debhelper compat to 10.
+  * d/p/drop-openstackdoctheme.patch: Dropped. No longer needed.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Thu, 25 Jan 2018 08:20:51 -0500
+
 python-openstackclient (3.12.0-3) unstable; urgency=medium
 
   * Add patch to fix output encoding that simply crashes the client.
@@ -397,6 +348,153 @@ python-openstackclient (3.12.0-1) experi
 
  -- Thomas Goirand <zigo@debian.org>  Tue, 03 Oct 2017 14:36:21 +0200
 
+python-openstackclient (3.12.0-0ubuntu2) artful; urgency=medium
+
+  * d/control: Set min python-requests to 2.14.2.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Thu, 03 Aug 2017 16:19:00 -0400
+
+python-openstackclient (3.12.0-0ubuntu1) artful; urgency=medium
+
+  * New upstream release.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/p/drop-openstackdoctheme.patch: Temporarily drop openstackdocstheme
+    sphinx extension until sphinx>=1.6.2 is available.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Wed, 02 Aug 2017 19:54:13 -0400
+
+python-openstackclient (3.11.0-0ubuntu1) artful; urgency=medium
+
+  * d/watch: Use tarballs.openstack.org.
+  * New upstream release for OpenStack Pike.
+  * Align (Build-)Depends with upstream release.
+
+ -- James Page <james.page@ubuntu.com>  Mon, 15 May 2017 18:42:30 +0100
+
+python-openstackclient (3.9.0-0ubuntu1) artful; urgency=medium
+
+  [ Chuck Short ]
+  * New upstream release.
+
+ -- James Page <james.page@ubuntu.com>  Fri, 21 Apr 2017 10:01:48 +0100
+
+python-openstackclient (3.8.1-0ubuntu3) zesty; urgency=medium
+
+  * debian/control: Dropped python3-hacking. 
+
+ -- Chuck Short <zulcss@ubuntu.com>  Sat, 04 Feb 2017 17:42:44 -0500
+
+python-openstackclient (3.8.1-0ubuntu2) zesty; urgency=medium
+
+  * debian/control: Dropped python-hacking. 
+
+ -- Chuck Short <zulcss@ubuntu.com>  Fri, 03 Feb 2017 21:49:07 -0500
+
+python-openstackclient (3.8.1-0ubuntu1) zesty; urgency=medium
+
+  * New upstream release.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Tue, 31 Jan 2017 09:38:38 -0500
+
+python-openstackclient (3.8.0-0ubuntu1) zesty; urgency=medium
+
+  * New upstream release. 
+  * d/control: Align (Build-)Depends with upstream.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Mon, 30 Jan 2017 13:31:03 -0500
+
+python-openstackclient (3.7.0-0ubuntu1) zesty; urgency=medium
+
+  * New upstream version.
+  * d/control: Align (Build-)Depends with upstream.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Tue, 17 Jan 2017 09:03:28 -0500
+
+python-openstackclient (3.6.0-0ubuntu1) zesty; urgency=medium
+
+  * New upstream release.
+  * d/control: Align (Build-)Depends with upstream.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Mon, 09 Jan 2017 09:28:05 -0500
+
+python-openstackclient (3.5.0-0ubuntu1) zesty; urgency=medium
+
+  * New upstream release.
+  * d/control: Align (Build-)Depends with upstream.
+  * d/p/max-images.patch: Dropped. Fixed in upstream release.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Fri, 16 Dec 2016 11:45:52 -0500
+
+python-openstackclient (3.4.1-0ubuntu2) zesty; urgency=medium
+
+  * debian/patches/max-images.patch: Allow more than maximum of 25 images to 
+    be listed. (LP: #1443089) 
+
+ -- Chuck Short <zulcss@ubuntu.com>  Mon, 12 Dec 2016 08:33:47 -0500
+
+python-openstackclient (3.4.1-0ubuntu1) zesty; urgency=medium
+
+  * New upstream version.
+  * debian/control: Bump version dependencies.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Mon, 21 Nov 2016 13:49:29 -0500
+
+python-openstackclient (3.3.0-1ubuntu1) zesty; urgency=medium
+
+  [ Corey Bryant ]
+  * d/gbp.conf: Update gbp configuration file.
+  * d/control: Update Vcs-* links and maintainers.
+
+  [ Chuck Short ]
+  * New upstream version.
+  * debian/control: Bump version dependencies.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Thu, 27 Oct 2016 11:40:04 -0400
+
+python-openstackclient (3.2.0-0ubuntu2) yakkety; urgency=medium
+
+  * Reduce scope of autopkgtests to drop requirement on openstack-deploy,
+    which is Debian only.
+
+ -- James Page <james.page@ubuntu.com>  Mon, 05 Sep 2016 11:15:15 +0100
+
+python-openstackclient (3.2.0-0ubuntu1) yakkety; urgency=medium
+
+  [ gustavo panizzo ]
+  * Add autopkgtest tests
+
+  [ Corey Bryant ]
+  * New usptream release.
+  * Align (Build-)Depends with upstream.
+  * d/p/0001-reproducible-build.patch: Dropped. Fixed upstream.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Fri, 02 Sep 2016 11:51:10 -0400
+
+python-openstackclient (2.6.0-1) experimental; urgency=medium
+
+  [ Corey Bryant ]
+  * New upstream release.
+  * Align (Build-)Depends with upstream.
+
+  [ Thomas Goirand ]
+  * Make build reproducible applying Lamby's patch (Closes: #826676).
+  * Unblacklist tests (they all work now...).
+  * Switch to using pkgos-dh_auto_{test,install}.
+
+ -- Thomas Goirand <zigo@debian.org>  Mon, 11 Jul 2016 14:58:15 +0200
+
+python-openstackclient (2.5.0-1) experimental; urgency=medium
+
+  [ Ondřej Nový ]
+  * Standards-Version is 3.9.8 now (no change)
+  * d/rules: Removed UPSTREAM_GIT with default value
+
+  [ Thomas Goirand ]
+  * New upstream release.
+  * Fixed (build-)depends for this release.
+
+ -- Thomas Goirand <zigo@debian.org>  Mon, 06 Jun 2016 08:06:59 +0000
+
 python-openstackclient (2.3.0-4) unstable; urgency=medium
 
   * Add Testsuite field to debian/control
@@ -553,3 +651,4 @@ python-openstackclient (0.3.0-1) unstabl
   * Initial release. (Closes: #733557)
 
  -- gustavo panizzo <gfa@zumbi.com.ar>  Tue, 31 Dec 2013 01:37:38 -0300
+
diff -pruN 7.4.0-3/debian/control 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/control
--- 7.4.0-3/debian/control	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/control	2025-08-05 16:47:42.000000000 +0000
@@ -1,72 +1,75 @@
 Source: python-openstackclient
 Section: python
 Priority: optional
-Maintainer: Debian OpenStack <team+openstack@tracker.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Debian OpenStack <openstack-devel@lists.alioth.debian.org>
 Uploaders:
  gustavo panizzo <gfa@zumbi.com.ar>,
  Thomas Goirand <zigo@debian.org>,
- Sakirnth Nagarasa <sakirnth@gmail.com>,
 Build-Depends:
- debhelper-compat (= 11),
+ debhelper-compat (= 13),
  dh-python,
  openstack-pkg-tools,
+ pybuild-plugin-pyproject,
  python3-all,
- python3-pbr,
+ python3-pbr (>= 2.0.0),
  python3-setuptools,
- python3-sphinx,
+ python3-sphinx (>= 2.0.0),
 Build-Depends-Indep:
- python3-aodhclient <!nodoc>,
- python3-barbicanclient <!nodoc>,
- python3-cinderclient,
- python3-cliff,
- python3-cloudkittyclient <!nodoc>,
- python3-coverage,
- python3-cryptography,
- python3-ddt,
- python3-designateclient <!nodoc>,
- python3-fixtures,
- python3-glanceclient,
- python3-gnocchiclient <!nodoc>,
- python3-hacking,
- python3-heatclient <!nodoc>,
- python3-ironic-inspector-client <!nodoc>,
- python3-ironicclient <!nodoc>,
- python3-iso8601,
- python3-keyring,
- python3-keystoneclient,
- python3-manilaclient <!nodoc>,
- python3-mistralclient <!nodoc>,
- python3-neutronclient <!nodoc>,
- python3-octaviaclient <!nodoc>,
- python3-openstackdocstheme <!nodoc>,
- python3-openstacksdk (>= 3.3.0),
- python3-osc-lib,
- python3-osc-placement,
- python3-oslo.i18n,
- python3-oslo.serialization,
- python3-osprofiler,
- python3-requests,
- python3-requests-mock,
- python3-searchlightclient <!nodoc>,
- python3-senlinclient <!nodoc>,
- python3-simplejson,
- python3-sphinxcontrib.apidoc <!nodoc>,
- python3-stestr <!nocheck>,
- python3-stevedore,
- python3-subunit <!nocheck>,
- python3-tempest <!nocheck>,
- python3-testtools <!nocheck>,
- python3-troveclient <!nodoc>,
- python3-watcherclient,
- python3-wrapt,
- python3-zaqarclient <!nodoc>,
- python3-zunclient <!nocheck>,
- python3-zunclient <!nodoc>,
+ python3-aodhclient (>= 0.9.0),
+ python3-babel (>= 2.3.4),
+ python3-barbicanclient (>= 4.5.2),
+ python3-cinderclient (>= 1:3.3.0),
+ python3-cliff (>= 4.8.0),
+ python3-cryptography (>= 2.7),
+ python3-cyborgclient (>= 1.2.1),
+ python3-ddt (>= 1.0.1),
+ python3-designateclient (>= 2.7.0),
+ python3-fixtures (>= 3.0.0),
+ python3-gnocchiclient (>= 3.3.1),
+ python3-hacking (>= 1.1.0),
+ python3-heatclient (>= 1.10.0),
+ python3-ironic-inspector-client (>= 1.5.0),
+ python3-ironicclient (>= 2.3.0),
+ python3-iso8601 (>= 0.1.11),
+ python3-keystoneclient (>= 1:3.22.0),
+ python3-magnumclient (>= 2.3.0),
+ python3-manilaclient (>= 2.0.0),
+ python3-mistralclient (>= 1:3.1.0),
+ python3-mock (>= 2.0.0),
+ python3-muranoclient (>= 0.8.2),
+ python3-neutronclient (>= 1:6.7.0),
+ python3-octaviaclient (>= 1.11.0),
+ python3-openstackdocstheme (>= 2.2.1),
+ python3-openstacksdk (>= 4.4.0),
+ python3-os-client-config (>= 1.28.0),
+ python3-osc-lib (>= 2.3.0),
+ python3-osc-placement (>= 1.7.0),
+ python3-oslo.i18n (>= 3.15.3),
+ python3-oslo.serialization (>= 1.2.0),
+ python3-oslo.utils (>= 3.33.0),
+ python3-oslotest (>= 1:3.2.0),
+ python3-osprofiler (>= 1.4.0),
+ python3-requests (>= 2.27.0),
+ python3-requests-mock (>= 1.2.0),
+ python3-saharaclient (>= 1.4.0),
+ python3-senlinclient (>= 1.1.0),
+ python3-sphinxcontrib.apidoc (>= 0.2.0),
+ python3-stestr (>= 1.0.0),
+ python3-stevedore (>= 1:2.0.1),
+ python3-subunit,
+ python3-tempest (>= 1:17.1.0),
+ python3-testtools (>= 2.2.0),
+ python3-troveclient (>= 1:3.1.0),
+ python3-watcherclient (>= 2.5.0),
+ python3-wrapt (>= 1.7.0),
+ python3-zaqarclient (>= 1.0.0),
+ python3-zunclient (>= 3.6.0),
  subunit,
-Standards-Version: 4.4.1
-Vcs-Browser: https://salsa.debian.org/openstack-team/clients/python-openstackclient
-Vcs-Git: https://salsa.debian.org/openstack-team/clients/python-openstackclient.git
-Homepage: http://wiki.openstack.org/OpenStackClient
+Standards-Version: 4.6.1
+Vcs-Git: https://git.launchpad.net/~ubuntu-openstack-dev/ubuntu/+source/python-openstackclient
+Homepage: https://opendev.org/openstack/python-openstackclient
+Testsuite: autopkgtest-pkg-python
 
 Package: python-openstackclient-doc
 Build-Profiles: <!nodoc>
@@ -90,26 +93,24 @@ Description: OpenStack Command-line Clie
 Package: python3-openstackclient
 Architecture: all
 Depends:
- python3-cinderclient,
- python3-cliff,
- python3-cryptography,
- python3-glanceclient,
- python3-iso8601,
- python3-keyring,
- python3-keystoneclient,
- python3-neutronclient,
- python3-openstacksdk (>= 3.3.0),
- python3-osc-lib,
- python3-oslo.i18n,
- python3-oslo.serialization,
- python3-pbr,
- python3-requests,
- python3-simplejson,
- python3-stevedore,
+ python3-babel (>= 2.3.4),
+ python3-cinderclient (>= 1:3.3.0),
+ python3-cliff (>= 4.8.0),
+ python3-cryptography (>= 2.7),
+ python3-iso8601 (>= 0.1.11),
+ python3-keystoneclient (>= 1:3.22.0),
+ python3-openstacksdk (>= 4.5.0),
+ python3-osc-lib (>= 2.3.0),
+ python3-osc-placement (>= 1.7.0),
+ python3-oslo.i18n (>= 3.15.3),
+ python3-oslo.serialization (>= 1.2.0),
+ python3-oslo.utils (>= 3.33.0),
+ python3-pbr (>= 2.0.0),
+ python3-requests (>= 2.27.0),
+ python3-stevedore (>= 1:2.0.1),
  ${misc:Depends},
  ${python3:Depends},
 Recommends:
- python-openstackclient-doc,
  ${python3:Recommends},
 Description: OpenStack Command-line Client - Python 3.x
  python-openstackclient is a unified command-line client for the OpenStack APIs.
diff -pruN 7.4.0-3/debian/copyright 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/copyright
--- 7.4.0-3/debian/copyright	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/copyright	2025-07-28 14:49:30.000000000 +0000
@@ -1,6 +1,6 @@
 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: python-openstackclient
-Source: http://wiki.openstack.org/OpenStackClient
+Source: https://opendev.org/openstack/python-openstackclient
 
 Files: *
 Copyright: (c) 2013-2014, OpenStack Foundation <openstack-dev@lists.openstack.org>
@@ -11,23 +11,11 @@ Copyright: (c) 2013-2014, OpenStack Foun
            (c) 2014, eBay Inc.
            (c) 2014-2015, CERN.
            (c) 2015, Symantec Corporation
-           (c) 2017, Huawei, Inc.
-           (c) 2020, Red Hat Inc.
-           (c) 2016, Intel Corporation.
-           (c) 2016, EasyStack Corporation
-           (c) 2015, Mirantis, Inc.
-           (c) 2016, IBM
-           (c) 2018, China Telecom Corporation
-           (c) 2016, NEC Corporation
-           (c) 2018, SUSE Linux GmbH
-           (c) 2019, SUSE LLC
-           (c) 2015, Dean Troyer
 License: Apache-2
 
 Files: debian/*
 Copyright: (c) 2013-2015, gustavo panizzo <gfa@zumbi.com.ar>
            (c) 2014-2016, Thomas Goirand <zigo@debian.org>
-           (c) 2021, Sakirnth Nagarasa <sakirnth@gmail.com>
 License: Apache-2
 
 License: Apache-2
diff -pruN 7.4.0-3/debian/exclude-list.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/exclude-list.txt
--- 7.4.0-3/debian/exclude-list.txt	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/exclude-list.txt	2025-07-28 14:49:30.000000000 +0000
@@ -0,0 +1 @@
+openstackclient.tests.unit.common.test_module.TestModuleList
diff -pruN 7.4.0-3/debian/gbp.conf 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/gbp.conf
--- 7.4.0-3/debian/gbp.conf	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/gbp.conf	2025-07-28 14:49:30.000000000 +0000
@@ -0,0 +1,9 @@
+[DEFAULT]
+debian-branch = master
+upstream-tag = %(version)s
+pristine-tar = True
+upstream-branch = upstream-flamingo
+
+[buildpackage]
+export-dir = ../build-area
+prebuild = [ ! -f .launchpad.yaml ] || rm .launchpad.yaml
diff -pruN 7.4.0-3/debian/patches/fix-pyproject-auto-discovery.patch 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/patches/fix-pyproject-auto-discovery.patch
--- 7.4.0-3/debian/patches/fix-pyproject-auto-discovery.patch	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/patches/fix-pyproject-auto-discovery.patch	2025-08-05 16:47:42.000000000 +0000
@@ -0,0 +1,29 @@
+Description: Build process failed to include submodules
+ This project moved to a pyproject.toml build process upstream
+ and the implementation failed to include the package submodules.
+ This patch uses the setuptools.packages.find feature to properly
+ build the flat layout of the project.
+Author: Myles Penner <myles.penner@canonical.com>
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/python-openstackclient/+bug/2119562
+Forwarded: no
+Last-Update: 2025-08-06
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+Index: python-openstackclient/pyproject.toml
+===================================================================
+--- python-openstackclient.orig/pyproject.toml
++++ python-openstackclient/pyproject.toml
+@@ -713,10 +713,9 @@ volume_transfer_request_show = "openstac
+ volume_summary = "openstackclient.volume.v3.volume:VolumeSummary"
+ volume_revert = "openstackclient.volume.v3.volume:VolumeRevertToSnapshot"
+ 
+-[tool.setuptools]
+-packages = [
+-    "openstackclient"
+-]
++[tool.setuptools.packages.find]
++include = ["openstackclient*"]
++exclude = ["openstackclient.tests*"]
+ 
+ [tool.mypy]
+ python_version = "3.10"
diff -pruN 7.4.0-3/debian/patches/series 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/patches/series
--- 7.4.0-3/debian/patches/series	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/patches/series	2025-08-05 16:47:42.000000000 +0000
@@ -0,0 +1 @@
+fix-pyproject-auto-discovery.patch
diff -pruN 7.4.0-3/debian/python3-openstackclient.postrm 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/python3-openstackclient.postrm
--- 7.4.0-3/debian/python3-openstackclient.postrm	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/python3-openstackclient.postrm	1970-01-01 00:00:00.000000000 +0000
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if [ "$1" = "remove" ] || [ "$1" = "disappear" ] ; then
-	update-alternatives --remove openstack /usr/bin/python3-openstack
-fi
-
-#DEBHELPER#
-
-exit 0
diff -pruN 7.4.0-3/debian/python3-openstackclient.prerm 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/python3-openstackclient.prerm
--- 7.4.0-3/debian/python3-openstackclient.prerm	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/python3-openstackclient.prerm	1970-01-01 00:00:00.000000000 +0000
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if [ "$1" = "remove" ] ; then
-	update-alternatives --remove openstack /usr/bin/python3-openstack
-fi
-
-#DEBHELPER#
-
-exit 0
diff -pruN 7.4.0-3/debian/rules 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/rules
--- 7.4.0-3/debian/rules	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/rules	2025-07-28 14:49:30.000000000 +0000
@@ -1,17 +1,15 @@
 #!/usr/bin/make -f
 
-include /usr/share/openstack-pkg-tools/pkgos.make
+export PYBUILD_NAME=openstackclient
 
-%:
-	dh $@ --with python3,sphinxdoc
+DEBVERS ?= $(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p')
+VERSION ?= $(shell echo '$(DEBVERS)' | sed -e 's/^[[:digit:]]*://' -e 's/[-].*//' -e 's/[+].*//' -e 's/~git.*//g' -e 's/~/./g')
+export PBR_VERSION=$(VERSION)
 
-override_dh_auto_clean:
-	rm -rf doc/build build .stestr *.egg-info doc/source/api doc/source/contributor/api
-	find . -iname '*.pyc' -delete
-	for i in $$(find . -type d -iname __pycache__) ; do rm -rf $$i ; done
+include /usr/share/openstack-pkg-tools/pkgos.make
 
-override_dh_auto_build:
-	echo "Do nothing..."
+%:
+	dh $@ --buildsystem=pybuild --with python3,sphinxdoc
 
 override_dh_auto_install:
 	pkgos-dh_auto_install --no-py2
@@ -19,23 +17,25 @@ override_dh_auto_install:
 	# Generate bash completion
 	pkgos-gen-completion --py3 openstack
 
+override_dh_auto_clean:
+	dh_auto_clean
+	rm -rf doc/build build .testrepository doc/source/api
+
 override_dh_auto_test:
 ifeq (,$(findstring nocheck, $(DEB_BUILD_OPTIONS)))
-	# See https://bugs.debian.org/1058097
-	pkgos-dh_auto_test --no-py2 'openstackclient\.tests\.unit\.(?!.*common\.test_module\.TestModuleList*)'
+	pkgos-dh_auto_test --no-py2 --exclude-list $(CURDIR)/debian/exclude-list.txt
 endif
 
 override_dh_sphinxdoc:
 ifeq (,$(findstring nodoc, $(DEB_BUILD_OPTIONS)))
-	python3 -m sphinx -b man doc/source doc/build/man
-	PYTHONPATH=. python3 -m sphinx -b html doc/source $(CURDIR)/debian/python-openstackclient-doc/usr/share/doc/python-openstackclient-doc/html
-	dh_sphinxdoc
-	cp debian/AUTHORS $(CURDIR)/debian/python-openstackclient-doc/usr/share/doc/python-openstackclient-doc
+	sphinx-build -b man doc/source doc/build/man
+	PYTHONPATH=. sphinx-build -b html doc/source $(CURDIR)/debian/python-openstackclient-doc/usr/share/doc/python-openstackclient-doc/html
+	dh_sphinxdoc -O--buildsystem=pybuild
 endif
 
 override_dh_installman:
 ifeq (,$(findstring nodoc, $(DEB_BUILD_OPTIONS)))
-	python3 -m sphinx -b man doc/source doc/build/man
+	sphinx-build -b man doc/source doc/build/man
 	dh_installman
 endif
 
diff -pruN 7.4.0-3/debian/salsa-ci.yml 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/salsa-ci.yml
--- 7.4.0-3/debian/salsa-ci.yml	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/salsa-ci.yml	1970-01-01 00:00:00.000000000 +0000
@@ -1,3 +0,0 @@
-include:
-  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
-  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
diff -pruN 7.4.0-3/debian/source/options 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/source/options
--- 7.4.0-3/debian/source/options	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/source/options	2025-07-28 14:49:30.000000000 +0000
@@ -1 +1,2 @@
 extend-diff-ignore = "^[^/]*[.]egg-info/"
+extend-diff-ignore = "^.launchpad.yaml"
diff -pruN 7.4.0-3/debian/tests/client 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/tests/client
--- 7.4.0-3/debian/tests/client	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/tests/client	2025-07-28 14:49:30.000000000 +0000
@@ -0,0 +1,16 @@
+#!/bin/bash
+#-------------------------
+# Testing client utilities
+#-------------------------
+set -e
+
+HELP_CLIENTS=('openstack')
+for client in "${HELP_CLIENTS[@]}"; do
+    if ! $client -h 2>&1 > /dev/null; then
+        echo "ERROR, ${client} is not running"
+        exit 1
+    else
+        echo "OK: ${client} is running"
+    fi
+done
+exit 0
diff -pruN 7.4.0-3/debian/tests/control 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/tests/control
--- 7.4.0-3/debian/tests/control	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/tests/control	2025-07-28 14:49:30.000000000 +0000
@@ -1,5 +1,3 @@
-Tests: unittests
+Tests: client
 Depends:
- @,
- @builddeps@,
-Restrictions: allow-stderr needs-root
+ python3-openstackclient,
diff -pruN 7.4.0-3/debian/tests/unittests 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/tests/unittests
--- 7.4.0-3/debian/tests/unittests	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/tests/unittests	1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-set -e
-
-pkgos-dh_auto_test --no-py2 'openstackclient\.tests\.unit\.(?!.*common\.test_module\.TestModuleList*)'
diff -pruN 7.4.0-3/debian/watch 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/watch
--- 7.4.0-3/debian/watch	2025-03-29 09:27:26.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/debian/watch	2025-07-28 14:49:30.000000000 +0000
@@ -1,3 +1,3 @@
-version=4
-opts="mode=git,uversionmangle=s/\.0rc/~rc/;s/\.0b1/~b1/;s/\.0b2/~b2/;s/\.0b3/~b3/;s/^2012/0.0.0/" \
-https://github.com/openstack/python-openstackclient refs/tags/(\d[brc\d\.]+)
+version=3
+opts="uversionmangle=s/\.(b|rc)/~$1/" \
+    http://tarballs.openstack.org/python-openstackclient/ python-openstackclient-(\d.*)\.tar\.gz
diff -pruN 7.4.0-3/doc/source/cli/_hidden/image.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/_hidden/image.rst
--- 7.4.0-3/doc/source/cli/_hidden/image.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/_hidden/image.rst	2025-07-07 22:41:56.000000000 +0000
@@ -3,7 +3,7 @@ image
 =====
 
 .. NOTE(efried): This page is hidden from the main TOC; it's here so links in
-   the wild redirect somewhere sane, because previously identity v2 and v3 were
+   the wild redirect somewhere sane, because previously image v2 and v3 were
    combined in a single page.
 
 .. toctree::
diff -pruN 7.4.0-3/doc/source/cli/command-objects/access-rules.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/access-rules.rst
--- 7.4.0-3/doc/source/cli/command-objects/access-rules.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/access-rules.rst	2025-07-07 22:41:56.000000000 +0000
@@ -9,53 +9,11 @@ rule comprises of a service type, a requ
 rules may only be created as attributes of application credentials, but they may
 be viewed and deleted independently.
 
+.. autoprogram-cliff:: openstack.identity.v3
+   :command: access rule delete
 
-access rule delete
-------------------
+.. autoprogram-cliff:: openstack.identity.v3
+   :command: access rule list
 
-Delete access rule(s)
-
-.. program:: access rule delete
-.. code:: bash
-
-    openstack access rule delete <access-rule> [<access-rule> ...]
-
-.. describe:: <access-rule>
-
-    Access rule(s) to delete (ID)
-
-access rule list
-----------------
-
-List access rules
-
-.. program:: access rule list
-.. code:: bash
-
-    openstack access rule list
-        [--user <user>]
-        [--user-domain <user-domain>]
-
-.. option:: --user
-
-    User whose access rules to list (name or ID). If not provided, looks up the
-    current user's access rules.
-
-.. option:: --user-domain
-
-    Domain the user belongs to (name or ID). This can be
-    used in case collisions between user names exist.
-
-access rule show
----------------------------
-
-Display access rule details
-
-.. program:: access rule show
-.. code:: bash
-
-    openstack access rule show <access-rule>
-
-.. describe:: <access-rule>
-
-    Access rule to display (ID)
+.. autoprogram-cliff:: openstack.identity.v3
+   :command: access rule show
diff -pruN 7.4.0-3/doc/source/cli/command-objects/consistency-group-snapshot.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/consistency-group-snapshot.rst
--- 7.4.0-3/doc/source/cli/command-objects/consistency-group-snapshot.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/consistency-group-snapshot.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,95 +2,16 @@
 consistency group snapshot
 ==========================
 
-Block Storage v2
+Block Storage v2, v3
 
-consistency group snapshot create
----------------------------------
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group snapshot create
 
-Create new consistency group snapshot.
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group snapshot delete
 
-.. program:: consistency group snapshot create
-.. code:: bash
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group snapshot list
 
-    openstack consistency group snapshot create
-        [--consistency-group <consistency-group>]
-        [--description <description>]
-        [<snapshot-name>]
-
-.. option:: --consistency-group <consistency-group>
-
-    Consistency group to snapshot (name or ID)
-    (default to be the same as <snapshot-name>)
-
-.. option:: --description <description>
-
-    Description of this consistency group snapshot
-
-.. _consistency_group_snapshot_create-snapshot-name:
-.. describe:: <snapshot-name>
-
-    Name of new consistency group snapshot (default to None)
-
-consistency group snapshot delete
----------------------------------
-
-Delete consistency group snapshot(s)
-
-.. program:: consistency group snapshot delete
-.. code:: bash
-
-    openstack consistency group snapshot delete
-        <consistency-group-snapshot> [<consistency-group-snapshot> ...]
-
-.. _consistency_group_snapshot_delete-consistency-group-snapshot:
-.. describe:: <consistency-group-snapshot>
-
-    Consistency group snapshot(s) to delete (name or ID)
-
-consistency group snapshot list
--------------------------------
-
-List consistency group snapshots.
-
-.. program:: consistency group snapshot list
-.. code:: bash
-
-    openstack consistency group snapshot list
-        [--all-projects]
-        [--long]
-        [--status <status>]
-        [--consistency-group <consistency-group>]
-
-.. option:: --all-projects
-
-    Show detail for all projects. Admin only.
-    (defaults to False)
-
-.. option:: --long
-
-    List additional fields in output
-
-.. option:: --status <status>
-
-    Filters results by a status
-    ("available", "error", "creating", "deleting" or "error_deleting")
-
-.. option:: --consistency-group <consistency-group>
-
-    Filters results by a consistency group (name or ID)
-
-consistency group snapshot show
--------------------------------
-
-Display consistency group snapshot details.
-
-.. program:: consistency group snapshot show
-.. code:: bash
-
-    openstack consistency group snapshot show
-        <consistency-group-snapshot>
-
-.. _consistency_group_snapshot_show-consistency-group-snapshot:
-.. describe:: <consistency-group-snapshot>
-
-    Consistency group snapshot to display (name or ID)
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group snapshot show
diff -pruN 7.4.0-3/doc/source/cli/command-objects/consistency-group.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/consistency-group.rst
--- 7.4.0-3/doc/source/cli/command-objects/consistency-group.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/consistency-group.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,172 +2,25 @@
 consistency group
 =================
 
-Block Storage v2
+Block Storage v2, v3
 
-consistency group add volume
-----------------------------
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group add volume
 
-Add volume(s) to consistency group.
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group create
 
-.. program:: consistency group add volume
-.. code:: bash
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group delete
 
-    openstack consistency group add volume
-        <consistency-group>
-        <volume> [<volume> ...]
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group list
 
-.. _consistency_group_add_volume:
-.. describe:: <consistency-group>
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group remove volume
 
-    Consistency group to contain <volume> (name or ID)
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group set
 
-.. describe:: <volume>
-
-    Volume(s) to add to <consistency-group> (name or ID)
-    (repeat option to add multiple volumes)
-
-consistency group create
-------------------------
-
-Create new consistency group.
-
-.. program:: consistency group create
-.. code:: bash
-
-    openstack consistency group create
-        --volume-type <volume-type> | --consistency-group-source <consistency-group> | --consistency-group-snapshot <consistency-group-snapshot>
-        [--description <description>]
-        [--availability-zone <availability-zone>]
-        [<name>]
-
-.. option:: --volume-type <volume-type>
-
-    Volume type of this consistency group (name or ID)
-
-.. option:: --consistency-group-source <consistency-group>
-
-    Existing consistency group (name or ID)
-
-.. option:: --consistency-group-snapshot <consistency-group-snapshot>
-
-    Existing consistency group snapshot (name or ID)
-
-.. option:: --description <description>
-
-    Description of this consistency group
-
-.. option:: --availability-zone <availability-zone>
-
-    Availability zone for this consistency group
-    (not available if creating consistency group from source)
-
-.. _consistency_group_create-name:
-.. describe:: <name>
-
-    Name of new consistency group (default to None)
-
-consistency group delete
-------------------------
-
-Delete consistency group(s).
-
-.. program:: consistency group delete
-.. code:: bash
-
-    openstack consistency group delete
-        [--force]
-        <consistency-group> [<consistency-group> ...]
-
-.. option:: --force
-
-    Allow delete in state other than error or available
-
-.. _consistency_group_delete-consistency-group:
-.. describe:: <consistency-group>
-
-    Consistency group(s) to delete (name or ID)
-
-consistency group list
-----------------------
-
-List consistency groups.
-
-.. program:: consistency group list
-.. code:: bash
-
-    openstack consistency group list
-        [--all-projects]
-        [--long]
-
-.. option:: --all-projects
-
-    Show detail for all projects. Admin only.
-    (defaults to False)
-
-.. option:: --long
-
-    List additional fields in output
-
-consistency group remove volume
--------------------------------
-
-Remove volume(s) from consistency group.
-
-.. program:: consistency group remove volume
-.. code:: bash
-
-    openstack consistency group remove volume
-        <consistency-group>
-        <volume> [<volume> ...]
-
-.. _consistency_group_remove_volume:
-.. describe:: <consistency-group>
-
-    Consistency group containing <volume> (name or ID)
-
-.. describe:: <volume>
-
-    Volume(s) to remove from <consistency-group> (name or ID)
-    (repeat option to remove multiple volumes)
-
-consistency group set
----------------------
-
-Set consistency group properties.
-
-.. program:: consistency group set
-.. code:: bash
-
-    openstack consistency group set
-        [--name <name>]
-        [--description <description>]
-        <consistency-group>
-
-.. option:: --name <name>
-
-    New consistency group name
-
-.. option:: --description <description>
-
-    New consistency group description
-
-.. _consistency_group_set-consistency-group:
-.. describe:: <consistency-group>
-
-    Consistency group to modify (name or ID)
-
-consistency group show
-----------------------
-
-Display consistency group details.
-
-.. program:: consistency group show
-.. code:: bash
-
-    openstack consistency group show
-        <consistency-group>
-
-.. _consistency_group_show-consistency-group:
-.. describe:: <consistency-group>
-
-    Consistency group to display (name or ID)
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: consistency group show
diff -pruN 7.4.0-3/doc/source/cli/command-objects/console-connection.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/console-connection.rst
--- 7.4.0-3/doc/source/cli/command-objects/console-connection.rst	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/console-connection.rst	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,10 @@
+==================
+console connection
+==================
+
+Server console connection information
+
+Compute v2
+
+.. autoprogram-cliff:: openstack.compute.v2
+   :command: console connection show
diff -pruN 7.4.0-3/doc/source/cli/command-objects/limits.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/limits.rst
--- 7.4.0-3/doc/source/cli/command-objects/limits.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/limits.rst	2025-07-07 22:41:56.000000000 +0000
@@ -4,7 +4,7 @@ limits
 
 The Compute and Block Storage APIs have resource usage limits.
 
-Compute v2, Block Storage v1
+Block Storage v2, v3; Compute v2
 
 
 .. autoprogram-cliff:: openstack.common
diff -pruN 7.4.0-3/doc/source/cli/command-objects/quota.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/quota.rst
--- 7.4.0-3/doc/source/cli/command-objects/quota.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/quota.rst	2025-07-07 22:41:56.000000000 +0000
@@ -5,7 +5,7 @@ quota
 Resource quotas appear in multiple APIs, OpenStackClient presents them as a
 single object with multiple properties.
 
-Block Storage v1, v2, Compute v2, Network v2
+Block Storage v1, v3; Compute v2; Network v2
 
 .. autoprogram-cliff:: openstack.common
    :command: quota *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/role-assignment.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/role-assignment.rst
--- 7.4.0-3/doc/source/cli/command-objects/role-assignment.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/role-assignment.rst	2025-07-07 22:41:56.000000000 +0000
@@ -4,103 +4,5 @@ role assignment
 
 Identity v2, v3
 
-role assignment list
---------------------
-
-List role assignments
-
-.. program:: role assignment list
-.. code:: bash
-
-    openstack role assignment list
-        [--role <role>]
-        [--role-domain <role-domain>]
-        [--user <user>]
-        [--user-domain <user-domain>]
-        [--group <group>]
-        [--group-domain <group-domain>]
-        [--domain <domain>]
-        [--project <project>]
-        [--project-domain <project-domain>]
-        [--effective]
-        [--inherited]
-        [--names]
-
-.. option:: --role <role>
-
-    Role to filter (name or ID)
-
-    .. versionadded:: 3
-
-.. option:: --role-domain <role-domain>
-
-    Domain the role belongs to (name or ID).
-    This can be used in case collisions between role names exist.
-
-    .. versionadded:: 3
-
-.. option:: --user <user>
-
-    User to filter (name or ID)
-
-.. option:: --user-domain <user-domain>
-
-    Domain the user belongs to (name or ID).
-    This can be used in case collisions between user names exist.
-
-    .. versionadded:: 3
-
-.. option:: --group <group>
-
-    Group to filter (name or ID)
-
-    .. versionadded:: 3
-
-.. option:: --group-domain <group-domain>
-
-    Domain the group belongs to (name or ID).
-    This can be used in case collisions between group names exist.
-
-    .. versionadded:: 3
-
-.. option:: --domain <domain>
-
-    Domain to filter (name or ID)
-
-    .. versionadded:: 3
-
-.. option:: --project <project>
-
-    Project to filter (name or ID)
-
-.. option:: --project-domain <project-domain>
-
-    Domain the project belongs to (name or ID).
-    This can be used in case collisions between project names exist.
-
-    .. versionadded:: 3
-
-.. option:: --effective
-
-    Returns only effective role assignments (defaults to False)
-
-    .. versionadded:: 3
-
-.. option:: --inherited
-
-    Specifies if the role grant is inheritable to the sub projects
-
-    .. versionadded:: 3
-
-.. option:: --names
-
-    Returns role assignments with names instead of IDs
-
-.. option:: --auth-user
-
-    Returns role assignments for the authenticated user.
-
-.. option:: --auth-project
-
-    Returns role assignments for the project to which the authenticated user
-    is scoped.
+.. autoprogram-cliff:: openstack.identity.v3
+   :command: role assignment list
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume-backup.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-backup.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume-backup.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-backup.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,7 +2,7 @@
 volume backup
 =============
 
-Block Storage v1, v2, v3
+Block Storage v2, v3
 
 .. autoprogram-cliff:: openstack.volume.v3
    :command: volume backup *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume-qos.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-qos.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume-qos.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-qos.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,7 +2,7 @@
 volume qos
 ==========
 
-Block Storage v1, v2, v3
+Block Storage v2, v3
 
 .. autoprogram-cliff:: openstack.volume.v3
    :command: volume qos *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume-service.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-service.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume-service.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-service.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,7 +2,7 @@
 volume service
 ==============
 
-Block Storage v1, v2, v3
+Block Storage v2, v3
 
 .. autoprogram-cliff:: openstack.volume.v3
    :command: volume service *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume-snapshot.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-snapshot.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume-snapshot.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-snapshot.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,7 +2,7 @@
 volume snapshot
 ===============
 
-Block Storage v1, v2, v3
+Block Storage v2, v3
 
 .. autoprogram-cliff:: openstack.volume.v3
    :command: volume snapshot *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume-transfer-request.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-transfer-request.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume-transfer-request.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-transfer-request.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,7 +2,7 @@
 volume transfer request
 =======================
 
-Block Storage v1, v2, v3
+Block Storage v2, v3
 
 .. autoprogram-cliff:: openstack.volume.v3
    :command: volume transfer request *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume-type.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-type.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume-type.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume-type.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,7 +2,7 @@
 volume type
 ===========
 
-Block Storage v1, v2, v3
+Block Storage v2, v3
 
 .. autoprogram-cliff:: openstack.volume.v3
    :command: volume type *
diff -pruN 7.4.0-3/doc/source/cli/command-objects/volume.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume.rst
--- 7.4.0-3/doc/source/cli/command-objects/volume.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/command-objects/volume.rst	2025-07-07 22:41:56.000000000 +0000
@@ -2,397 +2,33 @@
 volume
 ======
 
-Block Storage v1, v2
+Block Storage v2, v3
 
-volume create
--------------
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume create
 
-Create new volume
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume delete
 
-.. program:: volume create
-.. code:: bash
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume list
 
-    openstack volume create
-        [--size <size>]
-        [--type <volume-type>]
-        [--image <image> | --snapshot <snapshot> | --source <volume> ]
-        [--description <description>]
-        [--availability-zone <availability-zone>]
-        [--consistency-group <consistency-group>]
-        [--property <key=value> [...] ]
-        [--hint <key=value> [...] ]
-        [--bootable | --non-bootable]
-        [--read-only | --read-write]
-        <name>
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume migrate
 
-.. option:: --size <size>
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume set
 
-    Volume size in GB
-    (Required unless --snapshot or --source is specified)
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume show
 
-.. option:: --type <volume-type>
-
-    Set the type of volume
-
-    Select ``<volume-type>`` from the available types as shown
-    by ``volume type list``.
-
-.. option:: --image <image>
-
-    Use ``<image>`` as source of volume (name or ID)
-
-    This is commonly used to create a boot volume for a server.
-
-.. option:: --snapshot <snapshot>
-
-    Use ``<snapshot>`` as source of volume (name or ID)
-
-.. option:: --source <volume>
-
-    Volume to clone (name or ID)
-
-.. option:: --description <description>
-
-    Volume description
-
-.. option:: --availability-zone <availability-zone>
-
-    Create volume in ``<availability-zone>``
-
-.. option:: --consistency-group <consistency-group>
-
-    Consistency group where the new volume belongs to
-
-.. option:: --property <key=value>
-
-    Set a property on this volume (repeat option to set multiple properties)
-
-.. option:: --hint <key=value>
-
-    Arbitrary scheduler hint key-value pairs to help boot an instance
-    (repeat option to set multiple hints)
-
-.. option:: --bootable
-
-    Mark volume as bootable
-
-.. option:: --non-bootable
-
-    Mark volume as non-bootable (default)
-
-.. option:: --read-only
-
-    Set volume to read-only access mode
-
-.. option:: --read-write
-
-    Set volume to read-write access mode (default)
-
-.. _volume_create-name:
-.. describe:: <name>
-
-    Volume name
-
-volume delete
--------------
-
-Delete volume(s)
-
-.. program:: volume delete
-.. code:: bash
-
-    openstack volume delete
-        [--force | --purge]
-        <volume> [<volume> ...]
-
-.. option:: --force
-
-    Attempt forced removal of volume(s), regardless of state (defaults to False)
-
-.. option:: --purge
-
-    Remove any snapshots along with volume(s) (defaults to False)
-
-    *Volume version 2 only*
-
-.. _volume_delete-volume:
-.. describe:: <volume>
-
-    Volume(s) to delete (name or ID)
-
-volume list
------------
-
-List volumes
-
-.. program:: volume list
-.. code:: bash
-
-    openstack volume list
-        [--project <project> [--project-domain <project-domain>]]
-        [--user <user> [--user-domain <user-domain>]]
-        [--name <name>]
-        [--status <status>]
-        [--all-projects]
-        [--long]
-        [--limit <num-volumes>]
-        [--marker <volume>]
-
-.. option:: --project <project>
-
-    Filter results by ``<project>`` (name or ID) (admin only)
-
-    *Volume version 2 only*
-
-.. option:: --project-domain <project-domain>
-
-    Domain the project belongs to (name or ID).
-
-    This can be used in case collisions between project names exist.
-
-    *Volume version 2 only*
-
-.. option:: --user <user>
-
-    Filter results by ``<user>`` (name or ID) (admin only)
-
-    *Volume version 2 only*
-
-.. option:: --user-domain <user-domain>
-
-    Domain the user belongs to (name or ID).
-
-    This can be used in case collisions between user names exist.
-
-    *Volume version 2 only*
-
-.. option:: --name <name>
-
-    Filter results by volume name
-
-.. option:: --status <status>
-
-    Filter results by status
-
-.. option:: --all-projects
-
-    Include all projects (admin only)
-
-.. option:: --long
-
-    List additional fields in output
-
-.. option:: --limit <num-volumes>
-
-    Maximum number of volumes to display
-
-.. option:: --marker <volume>
-
-    The last volume ID of the previous page
-
-    *Volume version 2 only*
-
-volume migrate
---------------
-
-Migrate volume to a new host
-
-.. program:: volume migrate
-.. code:: bash
-
-    openstack volume migrate
-        --host <host>
-        [--force-host-copy]
-        [--lock-volume]
-        <volume>
-
-.. option:: --host <host>
-
-    Destination host (takes the form: host@backend-name#pool) (required)
-
-.. option:: --force-host-copy
-
-    Enable generic host-based force-migration,
-    which bypasses driver optimizations
-
-.. option:: --lock-volume
-
-    If specified, the volume state will be locked and will not allow
-    a migration to be aborted (possibly by another operation)
-
-    *Volume version 2 only*
-
-.. _volume_migrate-volume:
-.. describe:: <volume>
-
-    Volume to migrate (name or ID)
-
-volume set
-----------
-
-Set volume properties
-
-.. program:: volume set
-.. code:: bash
-
-    openstack volume set
-        [--name <name>]
-        [--size <size>]
-        [--description <description>]
-        [--no-property]
-        [--property <key=value> [...] ]
-        [--image-property <key=value> [...] ]
-        [--state <state>]
-        [--attached | --detached ]
-        [--type <volume-type>]
-        [--retype-policy <retype-policy>]
-        [--bootable | --non-bootable]
-        [--read-only | --read-write]
-        <volume>
-
-.. option:: --name <name>
-
-    New volume name
-
-.. option:: --size <size>
-
-    Extend volume size in GB
-
-.. option:: --description <description>
-
-    New volume description
-
-.. option:: --no-property
-
-    Remove all properties from :ref:`\<volume\> <volume_set-volume>`
-    (specify both :option:`--no-property` and :option:`--property` to
-    remove the current properties before setting new properties.)
-
-.. option:: --property <key=value>
-
-    Set a property on this volume (repeat option to set multiple properties)
-
-.. option:: --type <volume-type>
-
-    New volume type (name or ID)
-
-    *Volume version 2 only*
-
-.. option:: --retype-policy <retype-policy>
-
-    Migration policy while re-typing volume
-    ("never" or "on-demand", default is "never" )
-    (available only when :option:`--type` option is specified)
-
-    *Volume version 2 only*
-
-.. option:: --bootable
-
-    Mark volume as bootable
-
-.. option:: --non-bootable
-
-    Mark volume as non-bootable
-
-.. option:: --read-only
-
-    Set volume to read-only access mode
-
-.. option:: --read-write
-
-    Set volume to read-write access mode
-
-.. option:: --image-property <key=value>
-
-    Set an image property on this volume
-    (repeat option to set multiple image properties)
-
-    Image properties are copied along with the image when creating a volume
-    using ``--image``.  Note that these properties are immutable on the image
-    itself, this option updates the copy attached to this volume.
-
-    *Volume version 2 only*
-
-.. option:: --state <state>
-
-    New volume state
-    ("available", "error", "creating", "deleting", "in-use",
-    "attaching", "detaching", "error_deleting" or "maintenance") (admin only)
-    (This option simply changes the state of the volume in the database with
-    no regard to actual status, exercise caution when using)
-
-    *Volume version 2 only*
-
-.. option:: --attached
-
-    Set volume attachment status to "attached" (admin only)
-    (This option simply changes the state of the volume in the database with
-    no regard to actual status, exercise caution when using)
-
-    *Volume version 2 only*
-
-.. option:: --deattach
-
-    Set volume attachment status to "detached" (admin only)
-    (This option simply changes the state of the volume in the database with
-    no regard to actual status, exercise caution when using)
-
-    *Volume version 2 only*
-
-.. _volume_set-volume:
-.. describe:: <volume>
-
-    Volume to modify (name or ID)
-
-volume show
------------
-
-Show volume details
-
-.. program:: volume show
-.. code:: bash
-
-    openstack volume show
-        <volume>
-
-.. _volume_show-volume:
-.. describe:: <volume>
-
-    Volume to display (name or ID)
-
-volume unset
-------------
-
-Unset volume properties
-
-.. program:: volume unset
-.. code:: bash
-
-    openstack volume unset
-        [--property <key>]
-        [--image-property <key>]
-        <volume>
-
-.. option:: --property <key>
-
-    Remove a property from volume (repeat option to remove multiple properties)
-
-.. option:: --image-property <key>
-
-    Remove an image property from volume
-    (repeat option to remove multiple image properties)
-
-    *Volume version 2 only*
-
-.. _volume_unset-volume:
-.. describe:: <volume>
-
-    Volume to modify (name or ID)
+.. autoprogram-cliff:: openstack.volume.v3
+   :command: volume unset
 
 Block Storage v3
 
- .. autoprogram-cliff:: openstack.volume.v3
-     :command: volume summary
+.. autoprogram-cliff:: openstack.volume.v3
+    :command: volume summary
 
- .. autoprogram-cliff:: openstack.volume.v3
-     :command: volume revert
+.. autoprogram-cliff:: openstack.volume.v3
+    :command: volume revert
diff -pruN 7.4.0-3/doc/source/cli/plugin-commands/index.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/plugin-commands/index.rst
--- 7.4.0-3/doc/source/cli/plugin-commands/index.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/cli/plugin-commands/index.rst	2025-07-07 22:41:56.000000000 +0000
@@ -25,10 +25,3 @@ Plugin Commands
    watcher
    zaqar
    zun
-
-.. TODO(efried): Make pages for the following once they're fixed.
-
-.. cue
-.. # cueclient is not in global-requirements
-.. # list-plugins:: openstack.mb.v1
-.. #   :detailed:
diff -pruN 7.4.0-3/doc/source/contributor/command-errors.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/command-errors.rst
--- 7.4.0-3/doc/source/contributor/command-errors.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/command-errors.rst	2025-07-07 22:41:56.000000000 +0000
@@ -41,7 +41,7 @@ opened.
         ## ...
 
         def take_action(self, parsed_args):
-            compute_client = self.app.client_manager.sdk_connection.compute
+            compute_client = self.app.client_manager.compute
 
             public_key = parsed_args.public_key
             if public_key:
diff -pruN 7.4.0-3/doc/source/contributor/index.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/index.rst
--- 7.4.0-3/doc/source/contributor/index.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/index.rst	2025-07-07 22:41:56.000000000 +0000
@@ -11,7 +11,6 @@
    command-wrappers
    command-errors
    command-logs
-   specs/commands
    plugins
    humaninterfaceguide
    api/modules
diff -pruN 7.4.0-3/doc/source/contributor/specs/command-objects/example.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/specs/command-objects/example.rst
--- 7.4.0-3/doc/source/contributor/specs/command-objects/example.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/specs/command-objects/example.rst	1970-01-01 00:00:00.000000000 +0000
@@ -1,86 +0,0 @@
-=======
-example
-=======
-
-This is a specification for the ``example`` command object. It is not intended
-to be a complete template for new commands since other actions, options
-and/or arguments may be used. You can include general specification information
-before the commands below. This information could include links to related material
-or descriptions of similar commands.
-
-[example API name] [example API version]
-
-example create
---------------
-
-Create new example
-
-.. program:: example create
-.. code:: bash
-
-    openstack example create
-        <name>
-
-.. describe:: <name>
-
-    New example name
-
-example delete
---------------
-
-Delete example(s)
-
-.. program:: example delete
-.. code:: bash
-
-    openstack example delete
-        <example> [<example> ...]
-
-.. describe:: <example>
-
-    Example(s) to delete (name or ID)
-
-example list
-------------
-
-List examples
-
-.. program:: example list
-.. code:: bash
-
-    openstack example list
-
-example set
------------
-
-Set example properties
-
-.. program:: example set
-.. code:: bash
-
-    openstack example set
-        [--name <new-name>]
-        <example>
-
-.. option:: --name <new-name>
-
-    New example name
-
-.. describe:: <example>
-
-    Example to modify (name or ID)
-
-example show
-------------
-
-Display example details
-
-.. program:: example show
-.. code:: bash
-
-    openstack example show
-        <example>
-
-.. describe:: <example>
-
-    Example to display (name or ID)
diff -pruN 7.4.0-3/doc/source/contributor/specs/commands.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/specs/commands.rst
--- 7.4.0-3/doc/source/contributor/specs/commands.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/specs/commands.rst	1970-01-01 00:00:00.000000000 +0000
@@ -1,44 +0,0 @@
-=============
-Command Specs
-=============
-
-Specifications for new commands, objects and actions are listed below.
-These specifications have not been implemented. See
-:ref:`command-list` for implemented commands and
-:ref:`command-structure` for implemented objects and actions.
-
-It is optional to propose a specifications patch for new commands,
-objects and actions here before submitting the implementation. Once your
-specifications patch merges then you may proceed with the implementation.
-Your implementation patches should move applicable portions of the
-specifications patch to the official :ref:`command-list`
-and :ref:`command-structure` documentation.
-
-Objects Specs
--------------
-
-Add specifications for new objects based on the ``example`` object.
-
-Actions Specs
--------------
-
-Add specifications for new actions based on the ``example`` action.
-
-.. toctree::
-   :maxdepth: 1
-
-   network-topology
-
-Commands Specs
---------------
-
-Add specifications for new commands based on the commands for the
-``example`` object. The ``example`` commands are not intended to
-be a complete template for new commands since other actions, options
-and/or arguments may be used.
-
-.. toctree::
-   :glob:
-   :maxdepth: 2
-
-   command-objects/*
diff -pruN 7.4.0-3/doc/source/contributor/specs/network-topology.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/specs/network-topology.rst
--- 7.4.0-3/doc/source/contributor/specs/network-topology.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/doc/source/contributor/specs/network-topology.rst	1970-01-01 00:00:00.000000000 +0000
@@ -1,44 +0,0 @@
-================
-network topology
-================
-
-A **network topology** shows a topological graph about
-devices which connect to the specific network. Also, it
-will return availability information for each individual
-device within the network as well. One other thing to note
-is that it is the intention for OSC to collect data from
-existing REST APIs
-
-Network v2
-
-network topology list
----------------------
-
-List network topologies
-
-.. program:: network topology list
-.. code:: bash
-
-    openstack network topology list
-        [--project <project>]
-
-.. option:: --project <project>
-
-    List network topologies for given project
-    (name or ID)
-
-network topology show
----------------------
-
-Show network topology details
-
-.. program:: network topology show
-.. code:: bash
-
-    openstack network topology show
-        <network>
-
-.. _network_topology_show-network:
-.. describe:: <network>
-
-    Show network topology for a specific network (name or ID)
diff -pruN 7.4.0-3/examples/object_api.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/examples/object_api.py
--- 7.4.0-3/examples/object_api.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/examples/object_api.py	2025-07-07 22:41:56.000000000 +0000
@@ -94,7 +94,7 @@ def run(opts):
     c_list = obj_api.container_list()
     print("Name\tCount\tBytes")
     for c in c_list:
-        print("%s\t%d\t%d" % (c['name'], c['count'], c['bytes']))
+        print(f"{c['name']}\t{c['count']}\t{c['bytes']}")
 
     if len(c_list) > 0:
         # See what is in the first container
diff -pruN 7.4.0-3/examples/osc-lib.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/examples/osc-lib.py
--- 7.4.0-3/examples/osc-lib.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/examples/osc-lib.py	2025-07-07 22:41:56.000000000 +0000
@@ -87,7 +87,7 @@ def run(opts):
     c_list = client_manager.object_store.container_list()
     print("Name\tCount\tBytes")
     for c in c_list:
-        print("%s\t%d\t%d" % (c['name'], c['count'], c['bytes']))
+        print(f"{c['name']}\t{c['count']}\t{c['bytes']}")
 
     if len(c_list) > 0:
         # See what is in the first container
diff -pruN 7.4.0-3/openstackclient/common/availability_zone.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/availability_zone.py
--- 7.4.0-3/openstackclient/common/availability_zone.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/availability_zone.py	2025-07-07 22:41:56.000000000 +0000
@@ -117,7 +117,7 @@ class ListAvailabilityZone(command.Liste
         return parser
 
     def _get_compute_availability_zones(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         try:
             data = list(compute_client.availability_zones(details=True))
         except sdk_exceptions.ForbiddenException:  # policy doesn't allow
@@ -172,17 +172,14 @@ class ListAvailabilityZone(command.Liste
         return result
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('Zone Name', 'Zone Status')
         if parsed_args.long:
-            columns = (
-                'Zone Name',
-                'Zone Status',
+            columns += (
                 'Zone Resource',
                 'Host Name',
                 'Service Name',
                 'Service Status',
             )
-        else:
-            columns = ('Zone Name', 'Zone Status')
 
         # Show everything by default.
         show_all = (
diff -pruN 7.4.0-3/openstackclient/common/clientmanager.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/clientmanager.py
--- 7.4.0-3/openstackclient/common/clientmanager.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/clientmanager.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,6 +18,7 @@
 import importlib
 import logging
 import sys
+import typing as ty
 
 from osc_lib import clientmanager
 from osc_lib import shell
@@ -26,7 +27,7 @@ import stevedore
 
 LOG = logging.getLogger(__name__)
 
-PLUGIN_MODULES = []
+PLUGIN_MODULES: list[ty.Any] = []
 
 USER_AGENT = 'python-openstackclient'
 
diff -pruN 7.4.0-3/openstackclient/common/envvars.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/envvars.py
--- 7.4.0-3/openstackclient/common/envvars.py	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/envvars.py	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,57 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import os
+
+from openstackclient.i18n import _
+
+
+def bool_from_str(value, strict=False):
+    true_strings = ('1', 't', 'true', 'on', 'y', 'yes')
+    false_strings = ('0', 'f', 'false', 'off', 'n', 'no')
+
+    if isinstance(value, bool):
+        return value
+
+    lowered = value.strip().lower()
+    if lowered in true_strings:
+        return True
+    elif lowered in false_strings or not strict:
+        return False
+
+    msg = _(
+        "Unrecognized value '%(value)s'; acceptable values are: %(valid)s"
+    ) % {
+        'value': value,
+        'valid': ', '.join(
+            f"'{s}'" for s in sorted(true_strings + false_strings)
+        ),
+    }
+    raise ValueError(msg)
+
+
+def boolenv(*vars, default=False):
+    """Search for the first defined of possibly many bool-like env vars.
+
+    Returns the first environment variable defined in vars, or returns the
+    default.
+
+    :param vars: Arbitrary strings to search for. Case sensitive.
+    :param default: The default to return if no value found.
+    :returns: A boolean corresponding to the value found, else the default if
+        no value found.
+    """
+    for v in vars:
+        value = os.environ.get(v, None)
+        if value:
+            return bool_from_str(value)
+    return default
diff -pruN 7.4.0-3/openstackclient/common/extension.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/extension.py
--- 7.4.0-3/openstackclient/common/extension.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/extension.py	2025-07-07 22:41:56.000000000 +0000
@@ -73,17 +73,9 @@ class ListExtension(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('Name', 'Alias', 'Description')
         if parsed_args.long:
-            columns = (
-                'Name',
-                'Alias',
-                'Description',
-                'Namespace',
-                'Updated At',
-                'Links',
-            )
-        else:
-            columns = ('Name', 'Alias', 'Description')
+            columns += ('Namespace', 'Updated At', 'Links')
 
         data = []
 
@@ -106,7 +98,7 @@ class ListExtension(command.Lister):
                 LOG.warning(message)
 
         if parsed_args.compute or show_all:
-            compute_client = self.app.client_manager.sdk_connection.compute
+            compute_client = self.app.client_manager.compute
             try:
                 data += compute_client.extensions()
             except Exception:
diff -pruN 7.4.0-3/openstackclient/common/limits.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/limits.py
--- 7.4.0-3/openstackclient/common/limits.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/limits.py	2025-07-07 22:41:56.000000000 +0000
@@ -122,7 +122,7 @@ class ShowLimits(command.Lister):
         volume_limits = None
 
         if self.app.client_manager.is_compute_endpoint_enabled():
-            compute_client = self.app.client_manager.sdk_connection.compute
+            compute_client = self.app.client_manager.compute
             compute_limits = compute_client.get_limits(
                 reserved=parsed_args.is_reserved, tenant_id=project_id
             )
diff -pruN 7.4.0-3/openstackclient/common/project_cleanup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/project_cleanup.py
--- 7.4.0-3/openstackclient/common/project_cleanup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/project_cleanup.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@ import getpass
 import logging
 import os
 import queue
+import typing as ty
 
 from cliff.formatters import table
 from osc_lib.command import command
@@ -35,7 +36,7 @@ def ask_user_yesno(msg):
     :return bool: User choice
     """
     while True:
-        answer = getpass._raw_input('{} [{}]: '.format(msg, 'y/n'))
+        answer = getpass.getpass('{} [{}]: '.format(msg, 'y/n'))
         if answer in ('y', 'Y', 'yes'):
             return True
         elif answer in ('n', 'N', 'no'):
@@ -100,7 +101,7 @@ class ProjectCleanup(command.Command):
             project_connect = sdk.connect_as_project(project)
 
         if project_connect:
-            status_queue = queue.Queue()
+            status_queue: queue.Queue[ty.Any] = queue.Queue()
             parsed_args.max_width = int(
                 os.environ.get('CLIFF_MAX_TERM_WIDTH', 0)
             )
diff -pruN 7.4.0-3/openstackclient/common/quota.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/quota.py
--- 7.4.0-3/openstackclient/common/quota.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/common/quota.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,6 +18,7 @@ import argparse
 import itertools
 import logging
 import sys
+import typing as ty
 
 from openstack import exceptions as sdk_exceptions
 from osc_lib.command import command
@@ -132,7 +133,7 @@ def get_compute_quotas(
     default=False,
 ):
     try:
-        client = app.client_manager.sdk_connection.compute
+        client = app.client_manager.compute
         if default:
             quota = client.get_quota_set_defaults(project_id)
         else:
@@ -176,25 +177,37 @@ def get_network_quotas(
     default=False,
 ):
     def _network_quota_to_dict(network_quota, detail=False):
-        if not isinstance(network_quota, dict):
-            dict_quota = network_quota.to_dict()
-        else:
-            dict_quota = network_quota
+        dict_quota = network_quota.to_dict(computed=False)
 
-        result = {}
+        if not detail:
+            return dict_quota
 
+        # Neutron returns quota details in dict which is in format like:
+        # {'resource_name': {'in_use': X, 'limit': Y, 'reserved': Z},
+        #  'resource_name_2': {'in_use': X2, 'limit': Y2, 'reserved': Z2}}
+        #
+        # but Nova and Cinder returns quota in different format, like:
+        # {'resource_name': X,
+        #  'resource_name_2': X2,
+        #  'usage': {
+        #     'resource_name': Y,
+        #     'resource_name_2': Y2
+        #  },
+        #  'reserved': {
+        #     'resource_name': Z,
+        #     'resource_name_2': Z2
+        #  }}
+        #
+        # so we need to make conversion to have data in same format from
+        # all of the services
+        result: dict[str, ty.Any] = {"usage": {}, "reservation": {}}
         for key, values in dict_quota.items():
             if values is None:
                 continue
-
-            # NOTE(slaweq): Neutron returns values with key "used" but Nova for
-            # example returns same data with key "in_use" instead. Because of
-            # that we need to convert Neutron key to the same as is returned
-            # from Nova to make result more consistent
-            if isinstance(values, dict) and 'used' in values:
-                values['in_use'] = values.pop("used")
-
-            result[key] = values
+            if isinstance(values, dict):
+                result[key] = values['limit']
+                result["reservation"][key] = values['reserved']
+                result["usage"][key] = values['used']
 
         return result
 
@@ -243,7 +256,7 @@ class ListQuota(command.Lister):
         return parser
 
     def _list_quota_compute(self, parsed_args, project_ids):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         result = []
 
         for project_id in project_ids:
@@ -278,7 +291,7 @@ class ListQuota(command.Lister):
             if default_result != project_result:
                 result += project_result
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'cores',
             'injected_files',
@@ -291,7 +304,7 @@ class ListQuota(command.Lister):
             'server_groups',
             'server_group_members',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'Project ID',
             'Cores',
             'Injected Files',
@@ -340,7 +353,7 @@ class ListQuota(command.Lister):
             if default_result != project_result:
                 result += project_result
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'backups',
             'backup_gigabytes',
@@ -349,7 +362,7 @@ class ListQuota(command.Lister):
             'snapshots',
             'volumes',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'Project ID',
             'Backups',
             'Backup Gigabytes',
@@ -395,7 +408,7 @@ class ListQuota(command.Lister):
             if default_result != project_result:
                 result += project_result
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'floating_ips',
             'networks',
@@ -407,7 +420,7 @@ class ListQuota(command.Lister):
             'subnets',
             'subnet_pools',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'Project ID',
             'Floating IPs',
             'Networks',
@@ -575,7 +588,7 @@ class SetQuota(common.NetDetectionMixin,
         network_kwargs = {}
 
         if self.app.client_manager.is_compute_endpoint_enabled():
-            compute_client = self.app.client_manager.sdk_connection.compute
+            compute_client = self.app.client_manager.compute
 
             for k, v in COMPUTE_QUOTAS.items():
                 value = getattr(parsed_args, k, None)
@@ -756,6 +769,19 @@ and ``server-group-members`` output for
             )
 
         info = {}
+        if parsed_args.usage:
+            info["reservation"] = compute_quota_info.pop("reservation", {})
+            info["reservation"].update(
+                volume_quota_info.pop("reservation", {})
+            )
+            info["reservation"].update(
+                network_quota_info.pop("reservation", {})
+            )
+
+            info["usage"] = compute_quota_info.pop("usage", {})
+            info["usage"].update(volume_quota_info.pop("usage", {}))
+            info["usage"].update(network_quota_info.pop("usage", {}))
+
         info.update(compute_quota_info)
         info.update(volume_quota_info)
         info.update(network_quota_info)
@@ -798,11 +824,11 @@ and ``server-group-members`` output for
                 if k not in ('usage', 'reservation')
             ]
 
-        columns = (
+        columns: tuple[str, ...] = (
             'resource',
             'limit',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'Resource',
             'Limit',
         )
@@ -881,7 +907,7 @@ class DeleteQuota(command.Command):
 
         # compute quotas
         if parsed_args.service in {'all', 'compute'}:
-            compute_client = self.app.client_manager.sdk_connection.compute
+            compute_client = self.app.client_manager.compute
             compute_client.revert_quota_set(project.id)
 
         # volume quotas
diff -pruN 7.4.0-3/openstackclient/compute/client.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/client.py
--- 7.4.0-3/openstackclient/compute/client.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/client.py	2025-07-07 22:41:56.000000000 +0000
@@ -11,7 +11,6 @@
 #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #   License for the specific language governing permissions and limitations
 #   under the License.
-#
 
 import logging
 
@@ -21,13 +20,11 @@ from openstackclient.i18n import _
 
 LOG = logging.getLogger(__name__)
 
+# global variables used when building the shell
 DEFAULT_API_VERSION = '2.1'
 API_VERSION_OPTION = 'os_compute_api_version'
 API_NAME = 'compute'
-API_VERSIONS = {
-    '2': 'openstack.connection.Connection',
-    '2.1': 'openstack.connection.Connection',
-}
+API_VERSIONS = ('2', '2.1')
 
 
 def make_client(instance):
@@ -49,3 +46,8 @@ def build_option_parser(parser):
         % DEFAULT_API_VERSION,
     )
     return parser
+
+
+def check_api_version(check_version):
+    # SDK supports auto-negotiation for us: always return True
+    return True
diff -pruN 7.4.0-3/openstackclient/compute/v2/agent.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/agent.py
--- 7.4.0-3/openstackclient/compute/v2/agent.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/agent.py	2025-07-07 22:41:56.000000000 +0000
@@ -56,7 +56,7 @@ class CreateAgent(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         # doing this since openstacksdk has decided not to support this
         # deprecated command
@@ -95,7 +95,7 @@ class DeleteAgent(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         result = 0
         for id in parsed_args.id:
             try:
@@ -114,7 +114,7 @@ class DeleteAgent(command.Command):
 
         if result > 0:
             total = len(parsed_args.id)
-            msg = _("%(result)s of %(total)s agents failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s agents failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -139,7 +139,7 @@ class ListAgent(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         columns = (
             "Agent ID",
             "Hypervisor",
@@ -194,7 +194,7 @@ class SetAgent(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         response = compute_client.get('/os-agents', microversion='2.1')
         sdk_exceptions.raise_from_response(response)
diff -pruN 7.4.0-3/openstackclient/compute/v2/aggregate.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/aggregate.py
--- 7.4.0-3/openstackclient/compute/v2/aggregate.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/aggregate.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@
 """Compute v2 Aggregate action implementations"""
 
 import logging
+import typing as ty
 
 from openstack import utils as sdk_utils
 from osc_lib.cli import format_columns
@@ -67,7 +68,7 @@ class AddAggregateHost(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         aggregate = compute_client.find_aggregate(
             parsed_args.aggregate, ignore_missing=False
@@ -110,7 +111,7 @@ class CreateAggregate(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         attrs = {'name': parsed_args.name}
 
@@ -146,7 +147,7 @@ class DeleteAggregate(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         result = 0
         for a in parsed_args.aggregate:
             try:
@@ -168,9 +169,10 @@ class DeleteAggregate(command.Command):
 
         if result > 0:
             total = len(parsed_args.aggregate)
-            msg = _(
-                "%(result)s of %(total)s aggregates failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s aggregates failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -188,13 +190,13 @@ class ListAggregate(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         aggregates = list(compute_client.aggregates())
 
         if sdk_utils.supports_microversion(compute_client, '2.41'):
-            column_headers = ("ID", "UUID")
-            columns = ("id", "uuid")
+            column_headers: tuple[str, ...] = ("ID", "UUID")
+            columns: tuple[str, ...] = ("id", "uuid")
         else:
             column_headers = ("ID",)
             columns = ("id",)
@@ -250,7 +252,7 @@ class RemoveAggregateHost(command.ShowOn
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         aggregate = compute_client.find_aggregate(
             parsed_args.aggregate, ignore_missing=False
@@ -307,7 +309,7 @@ class SetAggregate(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         aggregate = compute_client.find_aggregate(
             parsed_args.aggregate, ignore_missing=False
         )
@@ -320,7 +322,7 @@ class SetAggregate(command.Command):
         if kwargs:
             compute_client.update_aggregate(aggregate.id, **kwargs)
 
-        properties = {}
+        properties: dict[str, ty.Any] = {}
         if parsed_args.no_property:
             # NOTE(RuiChen): "availability_zone" can not be unset from
             # properties. It is already excluded from show and create output.
@@ -352,7 +354,7 @@ class ShowAggregate(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         aggregate = compute_client.find_aggregate(
             parsed_args.aggregate, ignore_missing=False
         )
@@ -392,7 +394,7 @@ class UnsetAggregate(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         aggregate = compute_client.find_aggregate(
             parsed_args.aggregate, ignore_missing=False
         )
@@ -427,7 +429,7 @@ class CacheImageForAggregate(command.Com
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if not sdk_utils.supports_microversion(compute_client, '2.81'):
             msg = _(
diff -pruN 7.4.0-3/openstackclient/compute/v2/console.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/console.py
--- 7.4.0-3/openstackclient/compute/v2/console.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/console.py	2025-07-07 22:41:56.000000000 +0000
@@ -25,10 +25,9 @@ from openstackclient.i18n import _
 def _get_console_columns(item):
     # To maintain backwards compatibility we need to rename sdk props to
     # whatever OSC was using before
-    column_map = {}
     hidden_columns = ['id', 'links', 'location', 'name']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -56,7 +55,7 @@ class ShowConsoleLog(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             name_or_id=parsed_args.server, ignore_missing=False
@@ -108,6 +107,13 @@ class ShowConsoleURL(command.ShowOne):
             help=_("Show SPICE console URL"),
         )
         type_group.add_argument(
+            '--spice-direct',
+            dest='url_type',
+            action='store_const',
+            const='spice-direct',
+            help=_("Show SPICE direct protocol native console URL"),
+        )
+        type_group.add_argument(
             '--rdp',
             dest='url_type',
             action='store_const',
@@ -131,7 +137,7 @@ class ShowConsoleURL(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
diff -pruN 7.4.0-3/openstackclient/compute/v2/console_connection.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/console_connection.py
--- 7.4.0-3/openstackclient/compute/v2/console_connection.py	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/console_connection.py	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,48 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+#
+
+"""Compute v2 Console auth token implementations."""
+
+from osc_lib.command import command
+from osc_lib import utils
+
+from openstackclient.i18n import _
+
+
+def _get_console_connection_columns(item):
+    column_map: dict[str, str] = {}
+    hidden_columns = ['id', 'location', 'name']
+    return utils.get_osc_show_columns_for_sdk_resource(
+        item, column_map, hidden_columns
+    )
+
+
+class ShowConsoleConnectionInformation(command.ShowOne):
+    _description = _("Show server's remote console connection information")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            'token',
+            metavar='<token>',
+            help=_("Nova console token to lookup"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+        data = compute_client.validate_console_auth_token(parsed_args.token)
+        display_columns, columns = _get_console_connection_columns(data)
+        data = utils.get_dict_properties(data, columns)
+
+        return (display_columns, data)
diff -pruN 7.4.0-3/openstackclient/compute/v2/flavor.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/flavor.py
--- 7.4.0-3/openstackclient/compute/v2/flavor.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/flavor.py	2025-07-07 22:41:56.000000000 +0000
@@ -149,7 +149,7 @@ class CreateFlavor(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         if parsed_args.project and parsed_args.public:
@@ -190,8 +190,7 @@ class CreateFlavor(command.ShowOne):
                 compute_client.flavor_add_tenant_access(flavor.id, project_id)
             except Exception as e:
                 msg = _(
-                    "Failed to add project %(project)s access to "
-                    "flavor: %(e)s"
+                    "Failed to add project %(project)s access to flavor: %(e)s"
                 )
                 LOG.error(msg, {'project': parsed_args.project, 'e': e})
         if parsed_args.properties:
@@ -224,7 +223,7 @@ class DeleteFlavor(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         result = 0
         for f in parsed_args.flavor:
             try:
@@ -242,7 +241,7 @@ class DeleteFlavor(command.Command):
 
         if result > 0:
             total = len(parsed_args.flavor)
-            msg = _("%(result)s of %(total)s flavors failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s flavors failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -297,7 +296,7 @@ class ListFlavor(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         # is_public is ternary - None means give all flavors,
         # True is public only and False is private only
         # By default Nova assumes True and gives admins public flavors
@@ -330,7 +329,7 @@ class ListFlavor(command.Lister):
             if parsed_args.long and not f.extra_specs:
                 compute_client.fetch_flavor_extra_specs(f)
 
-        columns = (
+        columns: tuple[str, ...] = (
             "id",
             "name",
             "ram",
@@ -346,7 +345,7 @@ class ListFlavor(command.Lister):
                 "extra_specs",
             )
 
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             "ID",
             "Name",
             "RAM",
@@ -404,9 +403,7 @@ class SetFlavor(command.Command):
         parser.add_argument(
             '--project',
             metavar='<project>',
-            help=_(
-                'Set flavor access to project (name or ID) ' '(admin only)'
-            ),
+            help=_('Set flavor access to project (name or ID) (admin only)'),
         )
         identity_common.add_project_domain_option_to_parser(parser)
         parser.add_argument(
@@ -421,7 +418,7 @@ class SetFlavor(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         try:
@@ -483,7 +480,7 @@ class SetFlavor(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
+                _("Command Failed: One or more of the operations failed")
             )
 
 
@@ -500,7 +497,7 @@ class ShowFlavor(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         flavor = compute_client.find_flavor(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
@@ -560,8 +557,7 @@ class UnsetFlavor(command.Command):
             '--project',
             metavar='<project>',
             help=_(
-                'Remove flavor access from project (name or ID) '
-                '(admin only)'
+                'Remove flavor access from project (name or ID) (admin only)'
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
@@ -569,7 +565,7 @@ class UnsetFlavor(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         try:
@@ -612,5 +608,5 @@ class UnsetFlavor(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
+                _("Command Failed: One or more of the operations failed")
             )
diff -pruN 7.4.0-3/openstackclient/compute/v2/host.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/host.py
--- 7.4.0-3/openstackclient/compute/v2/host.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/host.py	2025-07-07 22:41:56.000000000 +0000
@@ -35,7 +35,7 @@ class ListHost(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         self.log.warning(
             "API has been deprecated; "
@@ -83,7 +83,7 @@ class SetHost(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         self.log.warning(
             "API has been deprecated; "
@@ -121,7 +121,7 @@ class ShowHost(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         self.log.warning(
             "API has been deprecated; "
diff -pruN 7.4.0-3/openstackclient/compute/v2/hypervisor.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/hypervisor.py
--- 7.4.0-3/openstackclient/compute/v2/hypervisor.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/hypervisor.py	2025-07-07 22:41:56.000000000 +0000
@@ -90,7 +90,7 @@ class ListHypervisor(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         list_opts = {}
 
@@ -119,14 +119,20 @@ class ListHypervisor(command.Lister):
         if parsed_args.matching:
             list_opts['hypervisor_hostname_pattern'] = parsed_args.matching
 
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             "ID",
             "Hypervisor Hostname",
             "Hypervisor Type",
             "Host IP",
             "State",
         )
-        columns = ('id', 'name', 'hypervisor_type', 'host_ip', 'state')
+        columns: tuple[str, ...] = (
+            'id',
+            'name',
+            'hypervisor_type',
+            'host_ip',
+            'state',
+        )
 
         if parsed_args.long:
             if not sdk_utils.supports_microversion(compute_client, '2.88'):
@@ -164,7 +170,7 @@ class ShowHypervisor(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         hypervisor_id = compute_client.find_hypervisor(
             parsed_args.hypervisor, ignore_missing=False, details=False
diff -pruN 7.4.0-3/openstackclient/compute/v2/hypervisor_stats.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/hypervisor_stats.py
--- 7.4.0-3/openstackclient/compute/v2/hypervisor_stats.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/hypervisor_stats.py	2025-07-07 22:41:56.000000000 +0000
@@ -42,7 +42,7 @@ class ShowHypervisorStats(command.ShowOn
     def take_action(self, parsed_args):
         # The command is deprecated since it is being dropped in Nova.
         self.log.warning(_("This command is deprecated."))
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         # We do API request directly cause this deprecated method is not and
         # will not be supported by OpenStackSDK.
         response = compute_client.get(
diff -pruN 7.4.0-3/openstackclient/compute/v2/keypair.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/keypair.py
--- 7.4.0-3/openstackclient/compute/v2/keypair.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/keypair.py	2025-07-07 22:41:56.000000000 +0000
@@ -61,14 +61,13 @@ def _generate_keypair():
 def _get_keypair_columns(item, hide_pub_key=False, hide_priv_key=False):
     # To maintain backwards compatibility we need to rename sdk props to
     # whatever OSC was using before
-    column_map = {}
     hidden_columns = ['links', 'location']
     if hide_pub_key:
         hidden_columns.append('public_key')
     if hide_priv_key:
         hidden_columns.append('private_key')
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -121,13 +120,12 @@ class CreateKeypair(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         kwargs = {'name': parsed_args.name}
 
         if parsed_args.public_key:
-            generated_keypair = None
             try:
                 with open(os.path.expanduser(parsed_args.public_key)) as p:
                     public_key = p.read()
@@ -230,7 +228,7 @@ class DeleteKeypair(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         kwargs = {}
@@ -258,13 +256,13 @@ class DeleteKeypair(command.Command):
             except Exception as e:
                 result += 1
                 LOG.error(
-                    _("Failed to delete key with name " "'%(name)s': %(e)s"),
+                    _("Failed to delete key with name '%(name)s': %(e)s"),
                     {'name': n, 'e': e},
                 )
 
         if result > 0:
             total = len(parsed_args.name)
-            msg = _("%(result)s of %(total)s keys failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s keys failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -300,8 +298,9 @@ class ListKeypair(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
+        identity_sdk_client = self.app.client_manager.sdk_connection.identity
 
         kwargs = {}
 
@@ -347,11 +346,17 @@ class ListKeypair(command.Lister):
                 parsed_args.project,
                 parsed_args.project_domain,
             ).id
-            users = identity_client.users.list(tenant_id=project)
+            assignments = identity_sdk_client.role_assignments(
+                scope_project_id=project
+            )
+            user_ids = set()
+            for assignment in assignments:
+                if assignment.user:
+                    user_ids.add(assignment.user['id'])
 
             data = []
-            for user in users:
-                kwargs['user_id'] = user.id
+            for user_id in user_ids:
+                kwargs['user_id'] = user_id
                 data.extend(compute_client.keypairs(**kwargs))
         elif parsed_args.user:
             if not sdk_utils.supports_microversion(compute_client, '2.10'):
@@ -372,7 +377,7 @@ class ListKeypair(command.Lister):
         else:
             data = compute_client.keypairs(**kwargs)
 
-        columns = ("Name", "Fingerprint")
+        columns: tuple[str, ...] = ("Name", "Fingerprint")
 
         if sdk_utils.supports_microversion(compute_client, '2.2'):
             columns += ("Type",)
@@ -411,7 +416,7 @@ class ShowKeypair(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         kwargs = {}
diff -pruN 7.4.0-3/openstackclient/compute/v2/server.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server.py
--- 7.4.0-3/openstackclient/compute/v2/server.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server.py	2025-07-07 22:41:56.000000000 +0000
@@ -21,7 +21,6 @@ import getpass
 import json
 import logging
 import os
-import typing as ty
 
 from cliff import columns as cliff_columns
 import iso8601
@@ -34,6 +33,7 @@ from osc_lib import exceptions
 from osc_lib import utils
 
 from openstackclient.api import compute_v2
+from openstackclient.common import envvars
 from openstackclient.common import pagination
 from openstackclient.i18n import _
 from openstackclient.identity import common as identity_common
@@ -184,6 +184,7 @@ def _prep_server_detail(compute_client,
         'user_data': 'OS-EXT-SRV-ATTR:user_data',
         'vm_state': 'OS-EXT-STS:vm_state',
         'pinned_availability_zone': 'pinned_availability_zone',
+        'scheduler_hints': 'scheduler_hints',
     }
     # Some columns returned by openstacksdk should not be shown because they're
     # either irrelevant or duplicates
@@ -204,7 +205,6 @@ def _prep_server_detail(compute_client,
         'min_count',
         'networks',
         'personality',
-        'scheduler_hints',
         # aliases
         'volumes',
         # unnecessary
@@ -235,6 +235,11 @@ def _prep_server_detail(compute_client,
 
     info = data
 
+    # NOTE(dviroel): microversion 2.100 is now retrieving scheduler_hints
+    #  content from request_spec on detailed responses
+    if not sdk_utils.supports_microversion(compute_client, '2.100'):
+        info.pop('scheduler_hints', None)
+
     # Convert the image blob to a name
     image_info = info.get('image', {})
     if image_info and any(image_info.values()):
@@ -321,49 +326,12 @@ def _prep_server_detail(compute_client,
             info['OS-EXT-STS:power_state']
         )
 
-    return info
-
-
-def bool_from_str(value, strict=False):
-    true_strings = ('1', 't', 'true', 'on', 'y', 'yes')
-    false_strings = ('0', 'f', 'false', 'off', 'n', 'no')
-
-    if isinstance(value, bool):
-        return value
-
-    lowered = value.strip().lower()
-    if lowered in true_strings:
-        return True
-    elif lowered in false_strings or not strict:
-        return False
-
-    msg = _(
-        "Unrecognized value '%(value)s'; acceptable values are: %(valid)s"
-    ) % {
-        'value': value,
-        'valid': ', '.join(
-            f"'{s}'" for s in sorted(true_strings + false_strings)
-        ),
-    }
-    raise ValueError(msg)
-
-
-def boolenv(*vars, default=False):
-    """Search for the first defined of possibly many bool-like env vars.
-
-    Returns the first environment variable defined in vars, or returns the
-    default.
+    if 'scheduler_hints' in info:
+        info['scheduler_hints'] = format_columns.DictListColumn(
+            info.pop('scheduler_hints', {}),
+        )
 
-    :param vars: Arbitrary strings to search for. Case sensitive.
-    :param default: The default to return if no value found.
-    :returns: A boolean corresponding to the value found, else the default if
-        no value found.
-    """
-    for v in vars:
-        value = os.environ.get(v, None)
-        if value:
-            return bool_from_str(value)
-    return default
+    return info
 
 
 class AddFixedIP(command.ShowOne):
@@ -399,7 +367,7 @@ class AddFixedIP(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
@@ -430,7 +398,7 @@ class AddFixedIP(command.ShowOne):
 
         interface = compute_client.create_server_interface(server.id, **kwargs)
 
-        columns = (
+        columns: tuple[str, ...] = (
             'port_id',
             'server_id',
             'net_id',
@@ -438,7 +406,7 @@ class AddFixedIP(command.ShowOne):
             'port_state',
             'fixed_ips',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'Port ID',
             'Server ID',
             'Network ID',
@@ -493,7 +461,7 @@ class AddFloatingIP(network_common.Netwo
         return parser
 
     def take_action_network(self, client, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         attrs = {}
         obj = client.find_ip(
@@ -586,7 +554,7 @@ class AddPort(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -640,7 +608,7 @@ class AddNetwork(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -691,7 +659,7 @@ class AddServerSecurityGroup(command.Com
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -793,7 +761,7 @@ with status ``SHELVED`` or ``SHELVED_OFF
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         volume_client = self.app.client_manager.sdk_connection.volume
 
         server = compute_client.find_server(
@@ -842,8 +810,13 @@ with status ``SHELVED`` or ``SHELVED_OFF
             **kwargs,
         )
 
-        columns = ('id', 'server id', 'volume id', 'device')
-        column_headers = ('ID', 'Server ID', 'Volume ID', 'Device')
+        columns: tuple[str, ...] = ('id', 'server id', 'volume id', 'device')
+        column_headers: tuple[str, ...] = (
+            'ID',
+            'Server ID',
+            'Volume ID',
+            'Device',
+        )
         if sdk_utils.supports_microversion(compute_client, '2.49'):
             columns += ('tag',)
             column_headers += ('Tag',)
@@ -1027,7 +1000,6 @@ class BDMLegacyAction(argparse.Action):
 
 class BDMAction(parseractions.MultiKeyValueAction):
     def __init__(self, option_strings, dest, **kwargs):
-        required_keys = []
         optional_keys = [
             'uuid',
             'source_type',
@@ -1045,7 +1017,7 @@ class BDMAction(parseractions.MultiKeyVa
         super().__init__(
             option_strings,
             dest,
-            required_keys=required_keys,
+            required_keys=[],
             optional_keys=optional_keys,
             **kwargs,
         )
@@ -1402,7 +1374,7 @@ class CreateServer(command.ShowOne):
             default=[],
             help=_(
                 'File(s) to inject into image before boot '
-                '(repeat option to set multiple files)'
+                '(repeat option to set multiple files) '
                 '(supported by --os-compute-api-version 2.57 or below)'
             ),
         )
@@ -1554,7 +1526,7 @@ class CreateServer(command.ShowOne):
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         volume_client = self.app.client_manager.volume
         image_client = self.app.client_manager.image
 
@@ -1617,8 +1589,7 @@ class CreateServer(command.ShowOne):
                 image = images[0]
             else:
                 msg = _(
-                    'No images match the property expected by '
-                    '--image-property'
+                    'No images match the property expected by --image-property'
                 )
                 raise exceptions.CommandError(msg)
 
@@ -1873,7 +1844,7 @@ class CreateServer(command.ShowOne):
 
             if 'delete_on_termination' in mapping:
                 try:
-                    value = bool_from_str(
+                    value = envvars.bool_from_str(
                         mapping['delete_on_termination'],
                         strict=True,
                     )
@@ -1902,7 +1873,7 @@ class CreateServer(command.ShowOne):
 
         # Default to empty list if nothing was specified and let nova
         # decide the default behavior.
-        networks: ty.Union[str, ty.List[ty.Dict[str, str]], None] = []
+        networks: str | list[dict[str, str]] | None = []
 
         if 'auto' in parsed_args.nics or 'none' in parsed_args.nics:
             if len(parsed_args.nics) > 1:
@@ -1967,7 +1938,7 @@ class CreateServer(command.ShowOne):
 
                 # convert from the novaclient-derived "NIC" view to the actual
                 # "network" view
-                network = {}
+                network: dict[str, str] = {}
 
                 if nic['net-id']:
                     network['uuid'] = nic['net-id']
@@ -1976,14 +1947,14 @@ class CreateServer(command.ShowOne):
                     network['port'] = nic['port-id']
 
                 if nic['v4-fixed-ip']:
-                    network['fixed'] = nic['v4-fixed-ip']
+                    network['fixed_ip'] = nic['v4-fixed-ip']
                 elif nic['v6-fixed-ip']:
-                    network['fixed'] = nic['v6-fixed-ip']
+                    network['fixed_ip'] = nic['v6-fixed-ip']
 
                 if nic.get('tag'):  # tags are optional
                     network['tag'] = nic['tag']
 
-                networks.append(network)
+                networks.append(network)  # type: ignore[union-attr]
 
         if not parsed_args.nics and sdk_utils.supports_microversion(
             compute_client, '2.37'
@@ -2195,7 +2166,7 @@ class CreateServerDump(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for name_or_id in parsed_args.server:
             server = compute_client.find_server(name_or_id)
             server.trigger_crash_dump(compute_client)
@@ -2220,7 +2191,7 @@ class DeleteServer(command.Command):
         parser.add_argument(
             '--all-projects',
             action='store_true',
-            default=boolenv('ALL_PROJECTS'),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_(
                 'Delete server(s) in another project by name (admin only)'
                 '(can be specified using the ALL_PROJECTS envvar)'
@@ -2239,7 +2210,7 @@ class DeleteServer(command.Command):
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_obj = compute_client.find_server(
                 server,
@@ -2386,7 +2357,7 @@ class ListServer(command.Lister):
         parser.add_argument(
             '--all-projects',
             action='store_true',
-            default=boolenv('ALL_PROJECTS'),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_(
                 'Include all projects (admin only) '
                 '(can be specified using the ALL_PROJECTS envvar)'
@@ -2424,8 +2395,7 @@ class ListServer(command.Lister):
         parser.add_argument(
             '--key-name',
             help=_(
-                'Search by keypair name '
-                '(admin only before microversion 2.83)'
+                'Search by keypair name (admin only before microversion 2.83)'
             ),
         )
         config_drive_group = parser.add_mutually_exclusive_group()
@@ -2648,7 +2618,7 @@ class ListServer(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
         image_client = self.app.client_manager.image
 
@@ -2804,12 +2774,12 @@ class ListServer(command.Lister):
                     msg % search_opts['changes-since']
                 )
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             'status',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Name',
             'Status',
@@ -2873,14 +2843,20 @@ class ListServer(command.Lister):
                 'pinned_availability_zone',
                 'hypervisor_hostname',
                 'metadata',
+                'scheduler_hints',
             )
             column_headers += (
                 'Availability Zone',
                 'Pinned Availability Zone',
                 'Host',
                 'Properties',
+                'Scheduler Hints',
             )
 
+        if parsed_args.all_projects:
+            columns += ('project_id',)
+            column_headers += ('Project ID',)
+
         # support for additional columns
         if parsed_args.columns:
             for c in parsed_args.columns:
@@ -2923,6 +2899,12 @@ class ListServer(command.Lister):
                 if c in ('Properties', "properties"):
                     columns += ('Metadata',)
                     column_headers += ('Properties',)
+                if c in (
+                    'scheduler_hints',
+                    "Scheduler Hints",
+                ):
+                    columns += ('scheduler_hints',)
+                    column_headers += ('Scheduler Hints',)
 
             # remove duplicates
             column_headers = tuple(dict.fromkeys(column_headers))
@@ -3025,7 +3007,7 @@ class ListServer(command.Lister):
                 # infrastructure failure situations.
                 # For those servers with partial constructs we just skip the
                 # processing of the image and flavor information.
-                if not hasattr(s, 'image') or not hasattr(s, 'flavor'):
+                if getattr(s, 'status') == 'UNKNOWN':
                     continue
 
             if 'id' in s.image and s.image.id is not None:
@@ -3089,6 +3071,7 @@ class ListServer(command.Lister):
                         'metadata': format_columns.DictColumn,
                         'security_groups_name': format_columns.ListColumn,
                         'hypervisor_hostname': HostColumn,
+                        'scheduler_hints': format_columns.DictListColumn,
                     },
                 )
                 for s in data
@@ -3124,7 +3107,7 @@ A non-admin user will not be able to exe
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         kwargs = {}
         if parsed_args.reason:
@@ -3222,7 +3205,7 @@ revert to release the new server and res
             action='store_true',
             default=None,
             help=_(
-                'Allow disk over-commit on the destination host'
+                'Allow disk over-commit on the destination host '
                 '(supported with --os-compute-api-version 2.24 or below)'
             ),
         )
@@ -3231,7 +3214,7 @@ revert to release the new server and res
             dest='disk_overcommit',
             action='store_false',
             help=_(
-                'Do not over-commit disk on the destination host (default)'
+                'Do not over-commit disk on the destination host (default) '
                 '(supported with --os-compute-api-version 2.24 or below)'
             ),
         )
@@ -3248,7 +3231,7 @@ revert to release the new server and res
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -3351,7 +3334,7 @@ class PauseServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -3400,7 +3383,7 @@ class RebootServer(command.Command):
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server_id = compute_client.find_server(
             parsed_args.server,
             ignore_missing=False,
@@ -3434,7 +3417,7 @@ class RebuildServer(command.ShowOne):
             '--image',
             metavar='<image>',
             help=_(
-                'Recreate server from the specified image (name or ID).'
+                'Recreate server from the specified image (name or ID). '
                 'Defaults to the currently used one.'
             ),
         )
@@ -3605,7 +3588,7 @@ class RebuildServer(command.ShowOne):
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         image_client = self.app.client_manager.image
 
         server = compute_client.find_server(
@@ -3866,7 +3849,7 @@ host."""
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         image_client = self.app.client_manager.image
 
         if parsed_args.host:
@@ -3899,9 +3882,15 @@ host."""
         compute_client.evacuate_server(server, **kwargs)
 
         if parsed_args.wait:
+            orig_status = server.status
+            success = ['ACTIVE']
+            if orig_status == 'SHUTOFF':
+                success.append('SHUTOFF')
+
             if utils.wait_for_status(
                 compute_client.get_server,
                 server.id,
+                success_status=success,
                 callback=_show_progress,
             ):
                 self.app.stdout.write(_('Complete\n'))
@@ -3931,7 +3920,7 @@ class RemoveFixedIP(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -3960,14 +3949,12 @@ class RemoveFloatingIP(network_common.Ne
         return parser
 
     def take_action_network(self, client, parsed_args):
-        attrs = {}
         obj = client.find_ip(
             parsed_args.ip_address,
             ignore_missing=False,
         )
-        attrs['port_id'] = None
 
-        client.update_ip(obj, **attrs)
+        client.update_ip(obj, port_id=None)
 
     def take_action_compute(self, client, parsed_args):
         server = client.find_server(parsed_args.server, ignore_missing=False)
@@ -3992,7 +3979,7 @@ class RemovePort(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -4031,7 +4018,7 @@ class RemoveNetwork(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -4075,7 +4062,7 @@ class RemoveServerSecurityGroup(command.
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -4145,7 +4132,7 @@ volume from a server with status ``SHELV
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         volume_client = self.app.client_manager.sdk_connection.volume
 
         server = compute_client.find_server(
@@ -4198,7 +4185,7 @@ server booted from a volume."""
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         image_client = self.app.client_manager.image
 
         image_ref = None
@@ -4252,7 +4239,7 @@ release the new server and restart the o
             '--revert',
             action="store_true",
             help=_(
-                '**Deprecated** Restore server state before resize'
+                '**Deprecated** Restore server state before resize. '
                 "Replaced by the 'openstack server resize revert' and "
                 "'openstack server migration revert' commands"
             ),
@@ -4270,7 +4257,7 @@ release the new server and restart the o
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
@@ -4332,7 +4319,7 @@ Confirm (verify) success of resize opera
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
@@ -4380,7 +4367,7 @@ one."""
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
@@ -4424,7 +4411,7 @@ class RestoreServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -4447,7 +4434,7 @@ class ResumeServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -4475,8 +4462,7 @@ class SetServer(command.Command):
         password_group.add_argument(
             '--password',
             help=_(
-                'Set the server password. '
-                'This option requires cloud support.'
+                'Set the server password. This option requires cloud support.'
             ),
         )
         password_group.add_argument(
@@ -4505,14 +4491,26 @@ class SetServer(command.Command):
             ),
         )
         parser.add_argument(
+            '--auto-approve',
+            action='store_true',
+            help=_(
+                "Allow server state override without asking for confirmation"
+            ),
+        )
+        parser.add_argument(
             '--state',
             metavar='<state>',
             choices=['active', 'error'],
             help=_(
-                'New server state '
-                '**WARNING** This can result in instances that are no longer '
-                'usable and should be used with caution '
-                '(admin only)'
+                'New server state.'
+                '**WARNING** Resetting the state is intended to work around '
+                'servers stuck in an intermediate state, such as deleting. '
+                'If the server is in an error state then this is almost '
+                'never the correct command to run and you should prefer hard '
+                'reboot where possible. In particular, if the server is in '
+                'an error state due to a move operation, setting the state '
+                'can result in instances that are no longer usable. Proceed '
+                'with caution. (admin only)'
             ),
         )
         parser.add_argument(
@@ -4547,8 +4545,22 @@ class SetServer(command.Command):
         )
         return parser
 
+    @staticmethod
+    def ask_user_yesno(msg):
+        """Ask user Y/N question
+
+        :param str msg: question text
+        :return bool: User choice
+        """
+        while True:
+            answer = getpass.getpass('{} [{}]: '.format(msg, 'y/n'))
+            if answer in ('y', 'Y', 'yes'):
+                return True
+            elif answer in ('n', 'N', 'no'):
+                return False
+
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
@@ -4597,6 +4609,17 @@ class SetServer(command.Command):
             )
 
         if parsed_args.state:
+            if not parsed_args.auto_approve:
+                if not self.ask_user_yesno(
+                    _(
+                        "Resetting the server state can make it much harder "
+                        "to recover a server from an error state. If the "
+                        "server is in error status due to a failed move "
+                        "operation then this is likely not the correct "
+                        "approach to fix the problem. Do you wish to continue?"
+                    )
+                ):
+                    return
             compute_client.reset_server_state(server, state=parsed_args.state)
 
         if parsed_args.root_password:
@@ -4666,7 +4689,7 @@ class ShelveServer(command.Command):
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server_ids = []
 
         for server in parsed_args.servers:
@@ -4761,7 +4784,7 @@ information for the server."""
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         image_client = self.app.client_manager.image
 
         server = compute_client.find_server(
@@ -4891,7 +4914,7 @@ class SshServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -4968,7 +4991,7 @@ class StartServer(command.Command):
         parser.add_argument(
             '--all-projects',
             action='store_true',
-            default=boolenv('ALL_PROJECTS'),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_(
                 'Start server(s) in another project by name (admin only) '
                 '(can be specified using the ALL_PROJECTS envvar)'
@@ -4977,7 +5000,7 @@ class StartServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -5003,16 +5026,16 @@ class StopServer(command.Command):
         parser.add_argument(
             '--all-projects',
             action='store_true',
-            default=boolenv('ALL_PROJECTS'),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_(
-                'Stop server(s) in another project by name (admin only)'
+                'Stop server(s) in another project by name (admin only) '
                 '(can be specified using the ALL_PROJECTS envvar)'
             ),
         )
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -5037,7 +5060,7 @@ class SuspendServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -5060,7 +5083,7 @@ class UnlockServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -5083,7 +5106,7 @@ class UnpauseServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         for server in parsed_args.server:
             server_id = compute_client.find_server(
                 server,
@@ -5105,7 +5128,7 @@ class UnrescueServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
         )
@@ -5172,7 +5195,7 @@ class UnsetServer(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
@@ -5263,7 +5286,7 @@ class UnshelveServer(command.Command):
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         kwargs = {}
 
         if parsed_args.availability_zone:
diff -pruN 7.4.0-3/openstackclient/compute/v2/server_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_backup.py
--- 7.4.0-3/openstackclient/compute/v2/server_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_backup.py	2025-07-07 22:41:56.000000000 +0000
@@ -71,7 +71,7 @@ class CreateServerBackup(command.ShowOne
                 self.app.stderr.write(f'\rProgress: {progress}')
                 self.app.stderr.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server, ignore_missing=False
diff -pruN 7.4.0-3/openstackclient/compute/v2/server_event.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_event.py
--- 7.4.0-3/openstackclient/compute/v2/server_event.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_event.py	2025-07-07 22:41:56.000000000 +0000
@@ -65,17 +65,11 @@ class ServerActionEventColumn(columns.Fo
     """
 
     def _format_event(self, event):
-        column_map = {}
         hidden_columns = ['id', 'name', 'location']
         _, columns = utils.get_osc_show_columns_for_sdk_resource(
-            event,
-            column_map,
-            hidden_columns,
-        )
-        data = utils.get_item_properties(
-            event,
-            columns,
+            event, {}, hidden_columns
         )
+        data = utils.get_item_properties(event, columns)
         return dict(zip(columns, data))
 
     def human_readable(self):
@@ -88,17 +82,14 @@ class ServerActionEventColumn(columns.Fo
 
 
 def _get_server_event_columns(item, client):
-    column_map = {}
-    hidden_columns = ['name', 'server_id', 'links', 'location']
+    hidden_columns = ['name', 'server_id', 'links', 'location', 'finish_time']
 
     if not sdk_utils.supports_microversion(client, '2.58'):
         # updated_at was introduced in 2.58
         hidden_columns.append('updated_at')
 
     return utils.get_osc_show_columns_for_sdk_resource(
-        item,
-        column_map,
-        hidden_columns,
+        item, {}, hidden_columns
     )
 
 
@@ -148,7 +139,7 @@ class ListServerEvent(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         kwargs = {}
 
@@ -220,13 +211,13 @@ class ListServerEvent(command.Lister):
 
         data = compute_client.server_actions(server_id, **kwargs)
 
-        columns = (
+        columns: tuple[str, ...] = (
             'request_id',
             'server_id',
             'action',
             'start_time',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'Request ID',
             'Server ID',
             'Action',
@@ -275,7 +266,7 @@ class ShowServerEvent(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         try:
             server_id = compute_client.find_server(
diff -pruN 7.4.0-3/openstackclient/compute/v2/server_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_group.py
--- 7.4.0-3/openstackclient/compute/v2/server_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -93,7 +93,7 @@ class CreateServerGroup(command.ShowOne)
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if parsed_args.policy in ('soft-affinity', 'soft-anti-affinity'):
             if not sdk_utils.supports_microversion(compute_client, '2.15'):
@@ -153,7 +153,7 @@ class DeleteServerGroup(command.Command)
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         result = 0
         for group in parsed_args.server_group:
             try:
@@ -197,7 +197,7 @@ class ListServerGroup(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         kwargs = {}
 
@@ -216,12 +216,12 @@ class ListServerGroup(command.Lister):
         if sdk_utils.supports_microversion(compute_client, '2.64'):
             policy_key = 'Policy'
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             policy_key.lower(),
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Name',
             policy_key,
@@ -264,7 +264,7 @@ class ShowServerGroup(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         group = compute_client.find_server_group(
             parsed_args.server_group, ignore_missing=False
         )
diff -pruN 7.4.0-3/openstackclient/compute/v2/server_image.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_image.py
--- 7.4.0-3/openstackclient/compute/v2/server_image.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_image.py	2025-07-07 22:41:56.000000000 +0000
@@ -72,7 +72,7 @@ class CreateServerImage(command.ShowOne)
                 self.app.stdout.write(f'\rProgress: {progress}')
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         image_client = self.app.client_manager.image
 
         server = compute_client.find_server(
diff -pruN 7.4.0-3/openstackclient/compute/v2/server_migration.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_migration.py
--- 7.4.0-3/openstackclient/compute/v2/server_migration.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_migration.py	2025-07-07 22:41:56.000000000 +0000
@@ -154,7 +154,7 @@ class ListMigration(command.Lister):
         )
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         identity_client = self.app.client_manager.identity
 
         search_opts = {}
@@ -289,7 +289,7 @@ class ShowMigration(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if not sdk_utils.supports_microversion(compute_client, '2.24'):
             msg = _(
@@ -333,7 +333,7 @@ class ShowMigration(command.ShowOne):
                 ignore_missing=False,
             )
 
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Server UUID',
             'Status',
@@ -352,7 +352,7 @@ class ShowMigration(command.ShowOne):
             'Updated At',
         )
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'server_id',
             'status',
@@ -404,7 +404,7 @@ class AbortMigration(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if not sdk_utils.supports_microversion(compute_client, '2.24'):
             msg = _(
@@ -469,7 +469,7 @@ class ForceCompleteMigration(command.Com
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if not sdk_utils.supports_microversion(compute_client, '2.22'):
             msg = _(
diff -pruN 7.4.0-3/openstackclient/compute/v2/server_volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_volume.py
--- 7.4.0-3/openstackclient/compute/v2/server_volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/server_volume.py	2025-07-07 22:41:56.000000000 +0000
@@ -34,7 +34,7 @@ class ListServerVolume(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         server = compute_client.find_server(
             parsed_args.server,
@@ -42,8 +42,8 @@ class ListServerVolume(command.Lister):
         )
         volumes = compute_client.volume_attachments(server)
 
-        columns = ()
-        column_headers = ()
+        columns: tuple[str, ...] = ()
+        column_headers: tuple[str, ...] = ()
 
         if not sdk_utils.supports_microversion(compute_client, '2.89'):
             columns += ('id',)
@@ -114,7 +114,7 @@ class SetServerVolume(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         volume_client = self.app.client_manager.sdk_connection.volume
 
         if parsed_args.delete_on_termination is not None:
diff -pruN 7.4.0-3/openstackclient/compute/v2/service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/service.py
--- 7.4.0-3/openstackclient/compute/v2/service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/service.py	2025-07-07 22:41:56.000000000 +0000
@@ -52,7 +52,7 @@ class DeleteService(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         result = 0
         for s in parsed_args.service:
             try:
@@ -70,7 +70,7 @@ class DeleteService(command.Command):
         if result > 0:
             total = len(parsed_args.service)
             msg = _(
-                "%(result)s of %(total)s compute services failed " "to delete."
+                "%(result)s of %(total)s compute services failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -108,8 +108,8 @@ deployment."""
         return parser
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
-        columns = (
+        compute_client = self.app.client_manager.compute
+        columns: tuple[str, ...] = (
             "id",
             "binary",
             "host",
@@ -118,7 +118,7 @@ deployment."""
             "state",
             "updated_at",
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             "ID",
             "Binary",
             "Host",
@@ -153,8 +153,7 @@ class SetService(command.Command):
             "service",
             metavar="<service>",
             help=_(
-                "Name of service (Binary name), for example "
-                "``nova-compute``"
+                "Name of service (Binary name), for example ``nova-compute``"
             ),
         )
         enabled_group = parser.add_mutually_exclusive_group()
@@ -222,7 +221,7 @@ class SetService(command.Command):
         return services[0]
 
     def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if (
             parsed_args.enable or not parsed_args.disable
@@ -281,9 +280,7 @@ class SetService(command.Command):
             force_down = False
         if force_down is not None:
             if not sdk_utils.supports_microversion(compute_client, '2.11'):
-                msg = _(
-                    '--os-compute-api-version 2.11 or later is ' 'required'
-                )
+                msg = _('--os-compute-api-version 2.11 or later is required')
                 raise exceptions.CommandError(msg)
             try:
                 compute_client.update_service_forced_down(
@@ -299,7 +296,6 @@ class SetService(command.Command):
 
         if result > 0:
             msg = _(
-                "Compute service %(service)s of host %(host)s failed to "
-                "set."
+                "Compute service %(service)s of host %(host)s failed to set."
             ) % {"service": parsed_args.service, "host": parsed_args.host}
             raise exceptions.CommandError(msg)
diff -pruN 7.4.0-3/openstackclient/compute/v2/usage.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/usage.py
--- 7.4.0-3/openstackclient/compute/v2/usage.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/compute/v2/usage.py	2025-07-07 22:41:56.000000000 +0000
@@ -115,8 +115,7 @@ class ListUsage(command.Lister):
             metavar="<start>",
             default=None,
             help=_(
-                "Usage range start date, ex 2012-01-20"
-                " (default: 4 weeks ago)"
+                "Usage range start date, ex 2012-01-20 (default: 4 weeks ago)"
             ),
         )
         parser.add_argument(
@@ -136,7 +135,7 @@ class ListUsage(command.Lister):
             else:
                 return project
 
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         columns = (
             "project_id",
             "server_usages",
@@ -222,8 +221,7 @@ class ShowUsage(command.ShowOne):
             metavar="<start>",
             default=None,
             help=_(
-                "Usage range start date, ex 2012-01-20"
-                " (default: 4 weeks ago)"
+                "Usage range start date, ex 2012-01-20 (default: 4 weeks ago)"
             ),
         )
         parser.add_argument(
@@ -236,7 +234,7 @@ class ShowUsage(command.ShowOne):
 
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.identity
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
         date_cli_format = "%Y-%m-%d"
         now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
 
diff -pruN 7.4.0-3/openstackclient/identity/client.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/client.py
--- 7.4.0-3/openstackclient/identity/client.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/client.py	2025-07-07 22:41:56.000000000 +0000
@@ -11,7 +11,6 @@
 #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #   License for the specific language governing permissions and limitations
 #   under the License.
-#
 
 import logging
 
@@ -20,9 +19,9 @@ from osc_lib import utils
 
 from openstackclient.i18n import _
 
-
 LOG = logging.getLogger(__name__)
 
+# global variables used when building the shell
 DEFAULT_API_VERSION = '3'
 API_VERSION_OPTION = 'os_identity_api_version'
 API_NAME = 'identity'
@@ -64,8 +63,7 @@ def build_option_parser(parser):
         metavar='<identity-api-version>',
         default=utils.env('OS_IDENTITY_API_VERSION'),
         help=_(
-            'Identity API version, default=%s '
-            '(Env: OS_IDENTITY_API_VERSION)'
+            'Identity API version, default=%s (Env: OS_IDENTITY_API_VERSION)'
         )
         % DEFAULT_API_VERSION,
     )
diff -pruN 7.4.0-3/openstackclient/identity/common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/common.py
--- 7.4.0-3/openstackclient/identity/common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/common.py	2025-07-07 22:41:56.000000000 +0000
@@ -88,23 +88,22 @@ def find_service_sdk(identity_client, na
         raise exceptions.CommandError(e.message)
 
     # search for service type
-    services = identity_client.services()
-    result = None
-    for service in services:
-        if name_type_or_id == service.type:
-            if result:
-                msg = _(
-                    "Multiple service matches found for '%s', "
-                    "use an ID or name to be more specific."
-                )
-                raise exceptions.CommandError(msg % name_type_or_id)
-            result = service
-
-    if result is None:
-        msg = _("No service with a type, name or ID of '%s' exists.")
-        raise exceptions.CommandError(msg % name_type_or_id)
+    services = identity_client.services(type=name_type_or_id)
+    try:
+        service = next(services)
+    except StopIteration:
+        msg = _(
+            "No service with a type, name or ID of '%(query)s' exists."
+        ) % {"query": name_type_or_id}
+        raise exceptions.CommandError(msg)
+
+    if next(services, None):
+        msg = _(
+            "Multiple service matches found for '%(query)s', use an ID to be more specific."
+        ) % {"query": name_type_or_id}
+        raise exceptions.CommandError(msg)
 
-    return result
+    return service
 
 
 def get_resource(manager, name_type_or_id):
@@ -190,6 +189,16 @@ def find_domain(identity_client, name_or
     )
 
 
+def find_domain_id_sdk(
+    identity_client, name_or_id, *, validate_actor_existence=True
+):
+    return _find_sdk_id(
+        identity_client.find_domain,
+        name_or_id=name_or_id,
+        validate_actor_existence=validate_actor_existence,
+    )
+
+
 def find_group(identity_client, name_or_id, domain_name_or_id=None):
     if domain_name_or_id is None:
         return _find_identity_resource(
@@ -205,6 +214,33 @@ def find_group(identity_client, name_or_
     )
 
 
+def find_group_id_sdk(
+    identity_client,
+    name_or_id,
+    domain_name_or_id=None,
+    *,
+    validate_actor_existence=True,
+):
+    if domain_name_or_id is None:
+        return _find_sdk_id(
+            identity_client.find_group,
+            name_or_id=name_or_id,
+            validate_actor_existence=validate_actor_existence,
+        )
+
+    domain_id = find_domain_id_sdk(
+        identity_client,
+        name_or_id=domain_name_or_id,
+        validate_actor_existence=validate_actor_existence,
+    )
+    return _find_sdk_id(
+        identity_client.find_group,
+        name_or_id=name_or_id,
+        validate_actor_existence=validate_actor_existence,
+        domain_id=domain_id,
+    )
+
+
 def find_project(identity_client, name_or_id, domain_name_or_id=None):
     if domain_name_or_id is None:
         return _find_identity_resource(
@@ -230,6 +266,32 @@ def find_user(identity_client, name_or_i
     )
 
 
+def find_user_id_sdk(
+    identity_client,
+    name_or_id,
+    domain_name_or_id=None,
+    *,
+    validate_actor_existence=True,
+):
+    if domain_name_or_id is None:
+        return _find_sdk_id(
+            identity_client.find_user,
+            name_or_id=name_or_id,
+            validate_actor_existence=validate_actor_existence,
+        )
+    domain_id = find_domain_id_sdk(
+        identity_client,
+        name_or_id=domain_name_or_id,
+        validate_actor_existence=validate_actor_existence,
+    )
+    return _find_sdk_id(
+        identity_client.find_user,
+        name_or_id=name_or_id,
+        validate_actor_existence=validate_actor_existence,
+        domain_id=domain_id,
+    )
+
+
 def _find_identity_resource(
     identity_client_manager, name_or_id, resource_type, **kwargs
 ):
@@ -270,13 +332,20 @@ def _find_identity_resource(
     return resource_type(None, {'id': name_or_id, 'name': name_or_id})
 
 
-def get_immutable_options(parsed_args):
-    options = {}
-    if parsed_args.immutable:
-        options['immutable'] = True
-    if parsed_args.no_immutable:
-        options['immutable'] = False
-    return options
+def _find_sdk_id(
+    find_command, name_or_id, *, validate_actor_existence=True, **kwargs
+):
+    try:
+        resource = find_command(
+            name_or_id=name_or_id, ignore_missing=False, **kwargs
+        )
+    except sdk_exceptions.ForbiddenException:
+        return name_or_id
+    except sdk_exceptions.ResourceNotFound as exc:
+        if not validate_actor_existence:
+            return name_or_id
+        raise exceptions.CommandError from exc
+    return resource.id
 
 
 def add_user_domain_option_to_parser(parser):
@@ -335,23 +404,27 @@ def add_inherited_option_to_parser(parse
         action='store_true',
         default=False,
         help=_(
-            'Specifies if the role grant is inheritable to the sub ' 'projects'
+            'Specifies if the role grant is inheritable to the sub projects'
         ),
     )
 
 
 def add_resource_option_to_parser(parser):
-    enable_group = parser.add_mutually_exclusive_group()
-    enable_group.add_argument(
+    immutable_group = parser.add_mutually_exclusive_group()
+    immutable_group.add_argument(
         '--immutable',
         action='store_true',
+        dest='immutable',
+        default=None,
         help=_(
             'Make resource immutable. An immutable project may not '
             'be deleted or modified except to remove the immutable flag'
         ),
     )
-    enable_group.add_argument(
+    immutable_group.add_argument(
         '--no-immutable',
-        action='store_true',
+        action='store_false',
+        dest='immutable',
+        default=None,
         help=_('Make resource mutable (default)'),
     )
diff -pruN 7.4.0-3/openstackclient/identity/v2_0/ec2creds.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/ec2creds.py
--- 7.4.0-3/openstackclient/identity/v2_0/ec2creds.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/ec2creds.py	2025-07-07 22:41:56.000000000 +0000
@@ -128,9 +128,10 @@ class DeleteEC2Creds(command.Command):
 
         if result > 0:
             total = len(parsed_args.access_keys)
-            msg = _(
-                "%(result)s of %(total)s EC2 keys failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s EC2 keys failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
diff -pruN 7.4.0-3/openstackclient/identity/v2_0/endpoint.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/endpoint.py
--- 7.4.0-3/openstackclient/identity/v2_0/endpoint.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/endpoint.py	2025-07-07 22:41:56.000000000 +0000
@@ -111,9 +111,10 @@ class DeleteEndpoint(command.Command):
 
         if result > 0:
             total = len(parsed_args.endpoints)
-            msg = _(
-                "%(result)s of %(total)s endpoints failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s endpoints failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -132,18 +133,19 @@ class ListEndpoint(command.Lister):
 
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.identity
+
+        columns: tuple[str, ...] = (
+            'ID',
+            'Region',
+            'Service Name',
+            'Service Type',
+        )
         if parsed_args.long:
-            columns = (
-                'ID',
-                'Region',
-                'Service Name',
-                'Service Type',
+            columns += (
                 'PublicURL',
                 'AdminURL',
                 'InternalURL',
             )
-        else:
-            columns = ('ID', 'Region', 'Service Name', 'Service Type')
         data = identity_client.endpoints.list()
 
         for ep in data:
diff -pruN 7.4.0-3/openstackclient/identity/v2_0/project.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/project.py
--- 7.4.0-3/openstackclient/identity/v2_0/project.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/project.py	2025-07-07 22:41:56.000000000 +0000
@@ -140,9 +140,10 @@ class DeleteProject(command.Command):
 
         if errors > 0:
             total = len(parsed_args.projects)
-            msg = _(
-                "%(errors)s of %(total)s projects failed " "to delete."
-            ) % {'errors': errors, 'total': total}
+            msg = _("%(errors)s of %(total)s projects failed to delete.") % {
+                'errors': errors,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -169,10 +170,9 @@ class ListProject(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('ID', 'Name')
         if parsed_args.long:
-            columns = ('ID', 'Name', 'Description', 'Enabled')
-        else:
-            columns = ('ID', 'Name')
+            columns += ('Description', 'Enabled')
         data = self.app.client_manager.identity.tenants.list()
         if parsed_args.sort:
             data = utils.sort_items(data, parsed_args.sort)
diff -pruN 7.4.0-3/openstackclient/identity/v2_0/role.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/role.py
--- 7.4.0-3/openstackclient/identity/v2_0/role.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/role.py	2025-07-07 22:41:56.000000000 +0000
@@ -143,7 +143,7 @@ class DeleteRole(command.Command):
 
         if errors > 0:
             total = len(parsed_args.roles)
-            msg = _("%(errors)s of %(total)s roles failed " "to delete.") % {
+            msg = _("%(errors)s of %(total)s roles failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
diff -pruN 7.4.0-3/openstackclient/identity/v2_0/service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/service.py
--- 7.4.0-3/openstackclient/identity/v2_0/service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/service.py	2025-07-07 22:41:56.000000000 +0000
@@ -100,9 +100,10 @@ class DeleteService(command.Command):
 
         if result > 0:
             total = len(parsed_args.services)
-            msg = _(
-                "%(result)s of %(total)s services failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s services failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -120,10 +121,9 @@ class ListService(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('ID', 'Name', 'Type')
         if parsed_args.long:
-            columns = ('ID', 'Name', 'Type', 'Description')
-        else:
-            columns = ('ID', 'Name', 'Type')
+            columns += ('Description',)
         data = self.app.client_manager.identity.services.list()
         return (
             columns,
@@ -164,7 +164,7 @@ class ShowService(command.ShowOne):
                     return zip(*sorted(info.items()))
 
             msg = _(
-                "No service catalog with a type, name or ID of '%s' " "exists."
+                "No service catalog with a type, name or ID of '%s' exists."
             ) % (parsed_args.service)
             raise exceptions.CommandError(msg)
         else:
diff -pruN 7.4.0-3/openstackclient/identity/v2_0/user.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/user.py
--- 7.4.0-3/openstackclient/identity/v2_0/user.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v2_0/user.py	2025-07-07 22:41:56.000000000 +0000
@@ -194,7 +194,7 @@ class DeleteUser(command.Command):
 
         if errors > 0:
             total = len(parsed_args.users)
-            msg = _("%(errors)s of %(total)s users failed " "to delete.") % {
+            msg = _("%(errors)s of %(total)s users failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
@@ -230,21 +230,11 @@ class ListUser(command.Lister):
             )
             project = project.id
 
+        columns: tuple[str, ...] = ('id', 'name')
+        column_headers: tuple[str, ...] = ('ID', 'Name')
         if parsed_args.long:
-            columns = (
-                'ID',
-                'Name',
-                'tenantId',
-                'Email',
-                'Enabled',
-            )
-            column_headers = (
-                'ID',
-                'Name',
-                'Project',
-                'Email',
-                'Enabled',
-            )
+            columns += ('tenantId', 'email', 'enabled')
+            column_headers += ('Project', 'Email', 'Enabled')
             # Cache the project list
             project_cache = {}
             try:
@@ -256,15 +246,10 @@ class ListUser(command.Lister):
             formatters['tenantId'] = functools.partial(
                 ProjectColumn, project_cache=project_cache
             )
-        else:
-            columns = column_headers = ('ID', 'Name')
         data = identity_client.users.list(tenant_id=project)
 
         if parsed_args.project:
-            d = {}
-            for s in data:
-                d[s.id] = s
-            data = d.values()
+            data = {s.id: s for s in data}.values()
 
         if parsed_args.long:
             # FIXME(dtroyer): Sometimes user objects have 'tenant_id' instead
diff -pruN 7.4.0-3/openstackclient/identity/v3/access_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/access_rule.py
--- 7.4.0-3/openstackclient/identity/v3/access_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/access_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -54,17 +54,14 @@ class DeleteAccessRule(command.Command):
             except Exception as e:
                 errors += 1
                 LOG.error(
-                    _(
-                        "Failed to delete access rule with "
-                        "ID '%(ac)s': %(e)s"
-                    ),
+                    _("Failed to delete access rule with ID '%(ac)s': %(e)s"),
                     {'ac': ac, 'e': e},
                 )
 
         if errors > 0:
             total = len(parsed_args.access_rule)
             msg = _(
-                "%(errors)s of %(total)s access rules failed " "to delete."
+                "%(errors)s of %(total)s access rules failed to delete."
             ) % {'errors': errors, 'total': total}
             raise exceptions.CommandError(msg)
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/application_credential.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/application_credential.py
--- 7.4.0-3/openstackclient/identity/v3/application_credential.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/application_credential.py	2025-07-07 22:41:56.000000000 +0000
@@ -20,6 +20,7 @@ import json
 import logging
 import uuid
 
+from cliff import columns as cliff_columns
 from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
@@ -27,10 +28,84 @@ from osc_lib import utils
 from openstackclient.i18n import _
 from openstackclient.identity import common
 
-
 LOG = logging.getLogger(__name__)
 
 
+class RolesColumn(cliff_columns.FormattableColumn):
+    """Generate a formatted string of role names."""
+
+    def human_readable(self):
+        return utils.format_list(r['name'] for r in self._value)
+
+
+def _format_application_credential(
+    application_credential, *, include_secret=False
+):
+    column_headers: tuple[str, ...] = (
+        'ID',
+        'Name',
+        'Description',
+        'Project ID',
+        'Roles',
+        'Unrestricted',
+        'Access Rules',
+        'Expires At',
+    )
+    columns: tuple[str, ...] = (
+        'id',
+        'name',
+        'description',
+        'project_id',
+        'roles',
+        'unrestricted',
+        'access_rules',
+        'expires_at',
+    )
+    if include_secret:
+        column_headers += ('Secret',)
+        columns += ('secret',)
+
+    return (
+        column_headers,
+        utils.get_item_properties(
+            application_credential, columns, formatters={'roles': RolesColumn}
+        ),
+    )
+
+
+def _format_application_credentials(application_credentials):
+    column_headers = (
+        'ID',
+        'Name',
+        'Description',
+        'Project ID',
+        'Roles',
+        'Unrestricted',
+        'Access Rules',
+        'Expires At',
+    )
+    columns = (
+        'id',
+        'name',
+        'description',
+        'project_id',
+        'roles',
+        'unrestricted',
+        'access_rules',
+        'expires_at',
+    )
+
+    return (
+        column_headers,
+        (
+            utils.get_item_properties(
+                x, columns, formatters={'roles': RolesColumn}
+            )
+            for x in application_credentials
+        ),
+    )
+
+
 # TODO(stephenfin): Move this to osc_lib since it's useful elsewhere
 def is_uuid_like(value) -> bool:
     """Returns validation of a value as a UUID.
@@ -38,9 +113,6 @@ def is_uuid_like(value) -> bool:
     :param val: Value to verify
     :type val: string
     :returns: bool
-
-    .. versionchanged:: 1.1.1
-       Support non-lowercase UUIDs.
     """
     try:
         formatted_value = (
@@ -179,31 +251,8 @@ class CreateApplicationCredential(comman
             access_rules=access_rules,
         )
 
-        # Format roles into something sensible
-        if application_credential['roles']:
-            roles = application_credential['roles']
-            msg = ' '.join(r['name'] for r in roles)
-            application_credential['roles'] = msg
-
-        columns = (
-            'id',
-            'name',
-            'description',
-            'project_id',
-            'roles',
-            'unrestricted',
-            'access_rules',
-            'expires_at',
-            'secret',
-        )
-        return (
-            columns,
-            (
-                utils.get_dict_properties(
-                    application_credential,
-                    columns,
-                )
-            ),
+        return _format_application_credential(
+            application_credential, include_secret=True
         )
 
 
@@ -252,6 +301,8 @@ class DeleteApplicationCredential(comman
             ) % {'errors': errors, 'total': total}
             raise exceptions.CommandError(msg)
 
+        return None
+
 
 class ListApplicationCredential(command.Lister):
     _description = _("List application credentials")
@@ -269,46 +320,19 @@ class ListApplicationCredential(command.
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.sdk_connection.identity
         if parsed_args.user:
-            user_id = common.find_user(
+            user_id = common.find_user_id_sdk(
                 identity_client, parsed_args.user, parsed_args.user_domain
-            ).id
+            )
         else:
             conn = self.app.client_manager.sdk_connection
             user_id = conn.config.get_auth().get_user_id(conn.identity)
 
-        data = identity_client.application_credentials(user=user_id)
-
-        data_formatted = []
-        for ac in data:
-            # Format roles into something sensible
-            roles = ac['roles']
-            msg = ' '.join(r['name'] for r in roles)
-            ac['roles'] = msg
-
-            data_formatted.append(ac)
-
-        columns = (
-            'ID',
-            'Name',
-            'Description',
-            'Project ID',
-            'Roles',
-            'Unrestricted',
-            'Access Rules',
-            'Expires At',
-        )
-        return (
-            columns,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                    formatters={},
-                )
-                for s in data_formatted
-            ),
+        application_credentials = identity_client.application_credentials(
+            user=user_id
         )
 
+        return _format_application_credentials(application_credentials)
+
 
 class ShowApplicationCredential(command.ShowOne):
     _description = _("Display application credential details")
@@ -327,31 +351,8 @@ class ShowApplicationCredential(command.
         conn = self.app.client_manager.sdk_connection
         user_id = conn.config.get_auth().get_user_id(conn.identity)
 
-        app_cred = identity_client.find_application_credential(
+        application_credential = identity_client.find_application_credential(
             user_id, parsed_args.application_credential
         )
 
-        # Format roles into something sensible
-        roles = app_cred['roles']
-        msg = ' '.join(r['name'] for r in roles)
-        app_cred['roles'] = msg
-
-        columns = (
-            'id',
-            'name',
-            'description',
-            'project_id',
-            'roles',
-            'unrestricted',
-            'access_rules',
-            'expires_at',
-        )
-        return (
-            columns,
-            (
-                utils.get_dict_properties(
-                    app_cred,
-                    columns,
-                )
-            ),
-        )
+        return _format_application_credential(application_credential)
diff -pruN 7.4.0-3/openstackclient/identity/v3/consumer.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/consumer.py
--- 7.4.0-3/openstackclient/identity/v3/consumer.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/consumer.py	2025-07-07 22:41:56.000000000 +0000
@@ -82,9 +82,10 @@ class DeleteConsumer(command.Command):
 
         if result > 0:
             total = len(parsed_args.consumer)
-            msg = _(
-                "%(result)s of %(total)s consumers failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s consumers failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/credential.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/credential.py
--- 7.4.0-3/openstackclient/identity/v3/credential.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/credential.py	2025-07-07 22:41:56.000000000 +0000
@@ -70,8 +70,7 @@ class CreateCredential(command.ShowOne):
             '--project',
             metavar='<project>',
             help=_(
-                'Project which limits the scope of '
-                'the credential (name or ID)'
+                'Project which limits the scope of the credential (name or ID)'
             ),
         )
         return parser
@@ -128,9 +127,10 @@ class DeleteCredential(command.Command):
 
         if result > 0:
             total = len(parsed_args.credential)
-            msg = _(
-                "%(result)s of %(total)s credential failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s credential failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -219,8 +219,7 @@ class SetCredential(command.Command):
             '--project',
             metavar='<project>',
             help=_(
-                'Project which limits the scope of '
-                'the credential (name or ID)'
+                'Project which limits the scope of the credential (name or ID)'
             ),
         )
         return parser
diff -pruN 7.4.0-3/openstackclient/identity/v3/domain.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/domain.py
--- 7.4.0-3/openstackclient/identity/v3/domain.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/domain.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,7 +17,7 @@
 
 import logging
 
-from keystoneauth1 import exceptions as ks_exc
+from openstack import exceptions as sdk_exceptions
 from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
@@ -29,6 +29,31 @@ from openstackclient.identity import com
 LOG = logging.getLogger(__name__)
 
 
+def _format_domain(domain):
+    columns = (
+        'id',
+        'name',
+        'is_enabled',
+        'description',
+        'options',
+    )
+    column_headers = (
+        'id',
+        'name',
+        'enabled',
+        'description',
+        'options',
+    )
+
+    return (
+        column_headers,
+        utils.get_item_properties(
+            domain,
+            columns,
+        ),
+    )
+
+
 class CreateDomain(command.ShowOne):
     _description = _("Create new domain")
 
@@ -47,12 +72,15 @@ class CreateDomain(command.ShowOne):
         enable_group = parser.add_mutually_exclusive_group()
         enable_group.add_argument(
             '--enable',
+            dest='is_enabled',
             action='store_true',
+            default=True,
             help=_('Enable domain (default)'),
         )
         enable_group.add_argument(
             '--disable',
-            action='store_true',
+            dest='is_enabled',
+            action='store_false',
             help=_('Disable domain'),
         )
         parser.add_argument(
@@ -64,32 +92,27 @@ class CreateDomain(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
-        enabled = True
-        if parsed_args.disable:
-            enabled = False
-
-        options = common.get_immutable_options(parsed_args)
+        options = {}
+        if parsed_args.immutable is not None:
+            options['immutable'] = parsed_args.immutable
 
         try:
-            domain = identity_client.domains.create(
+            domain = identity_client.create_domain(
                 name=parsed_args.name,
                 description=parsed_args.description,
                 options=options,
-                enabled=enabled,
+                is_enabled=parsed_args.is_enabled,
             )
-        except ks_exc.Conflict:
+        except sdk_exceptions.ConflictException:
             if parsed_args.or_show:
-                domain = utils.find_resource(
-                    identity_client.domains, parsed_args.name
-                )
+                domain = identity_client.find_domain(parsed_args.name)
                 LOG.info(_('Returning existing domain %s'), domain.name)
             else:
                 raise
 
-        domain._info.pop('links')
-        return zip(*sorted(domain._info.items()))
+        return _format_domain(domain)
 
 
 class DeleteDomain(command.Command):
@@ -106,12 +129,12 @@ class DeleteDomain(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
         result = 0
         for i in parsed_args.domain:
             try:
-                domain = utils.find_resource(identity_client.domains, i)
-                identity_client.domains.delete(domain.id)
+                domain = identity_client.find_domain(i, ignore_missing=False)
+                identity_client.delete_domain(domain.id)
             except Exception as e:
                 result += 1
                 LOG.error(
@@ -124,7 +147,7 @@ class DeleteDomain(command.Command):
 
         if result > 0:
             total = len(parsed_args.domain)
-            msg = _("%(result)s of %(total)s domains failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s domains failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -143,7 +166,7 @@ class ListDomain(command.Lister):
         )
         parser.add_argument(
             '--enabled',
-            dest='enabled',
+            dest='is_enabled',
             action='store_true',
             help=_('The domains that are enabled will be returned'),
         )
@@ -153,13 +176,17 @@ class ListDomain(command.Lister):
         kwargs = {}
         if parsed_args.name:
             kwargs['name'] = parsed_args.name
-        if parsed_args.enabled:
-            kwargs['enabled'] = True
+        if parsed_args.is_enabled:
+            kwargs['is_enabled'] = True
+
+        columns = ('id', 'name', 'is_enabled', 'description')
+        column_headers = ('ID', 'Name', 'Enabled', 'Description')
+        data = self.app.client_manager.sdk_connection.identity.domains(
+            **kwargs
+        )
 
-        columns = ('ID', 'Name', 'Enabled', 'Description')
-        data = self.app.client_manager.identity.domains.list(**kwargs)
         return (
-            columns,
+            column_headers,
             (
                 utils.get_item_properties(
                     s,
@@ -194,38 +221,35 @@ class SetDomain(command.Command):
         enable_group = parser.add_mutually_exclusive_group()
         enable_group.add_argument(
             '--enable',
+            dest='is_enabled',
             action='store_true',
+            default=None,
             help=_('Enable domain'),
         )
         enable_group.add_argument(
             '--disable',
-            action='store_true',
+            dest='is_enabled',
+            action='store_false',
+            default=None,
             help=_('Disable domain'),
         )
         common.add_resource_option_to_parser(parser)
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
-        domain = utils.find_resource(
-            identity_client.domains, parsed_args.domain
-        )
+        identity_client = self.app.client_manager.sdk_connection.identity
+        domain = identity_client.find_domain(parsed_args.domain)
         kwargs = {}
         if parsed_args.name:
             kwargs['name'] = parsed_args.name
         if parsed_args.description:
             kwargs['description'] = parsed_args.description
+        if parsed_args.is_enabled is not None:
+            kwargs['is_enabled'] = parsed_args.is_enabled
+        if parsed_args.immutable is not None:
+            kwargs['options'] = {'immutable': parsed_args.immutable}
 
-        if parsed_args.enable:
-            kwargs['enabled'] = True
-        if parsed_args.disable:
-            kwargs['enabled'] = False
-
-        options = common.get_immutable_options(parsed_args)
-        if options:
-            kwargs['options'] = options
-
-        identity_client.domains.update(domain.id, **kwargs)
+        identity_client.update_domain(domain.id, **kwargs)
 
 
 class ShowDomain(command.ShowOne):
@@ -241,13 +265,7 @@ class ShowDomain(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
-
-        domain_str = common._get_token_resource(
-            identity_client, 'domain', parsed_args.domain
-        )
-
-        domain = utils.find_resource(identity_client.domains, domain_str)
+        identity_client = self.app.client_manager.sdk_connection.identity
+        domain = identity_client.find_domain(parsed_args.domain)
 
-        domain._info.pop('links')
-        return zip(*sorted(domain._info.items()))
+        return _format_domain(domain)
diff -pruN 7.4.0-3/openstackclient/identity/v3/ec2creds.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/ec2creds.py
--- 7.4.0-3/openstackclient/identity/v3/ec2creds.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/ec2creds.py	2025-07-07 22:41:56.000000000 +0000
@@ -156,9 +156,10 @@ class DeleteEC2Creds(command.Command):
 
         if result > 0:
             total = len(parsed_args.access_key)
-            msg = _(
-                "%(result)s of %(total)s EC2 keys failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s EC2 keys failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/endpoint.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/endpoint.py
--- 7.4.0-3/openstackclient/identity/v3/endpoint.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/endpoint.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,11 +28,31 @@ from openstackclient.identity import com
 LOG = logging.getLogger(__name__)
 
 
-def get_service_name(service):
-    if hasattr(service, 'name'):
-        return service.name
-    else:
-        return ''
+def _format_endpoint(endpoint, service):
+    columns = (
+        'is_enabled',
+        'id',
+        'interface',
+        'region_id',
+        'region_id',
+        'service_id',
+        'url',
+    )
+    column_headers = (
+        'enabled',
+        'id',
+        'interface',
+        'region',
+        'region_id',
+        'service_id',
+        'url',
+        'service_name',
+        'service_type',
+    )
+
+    data = utils.get_item_properties(endpoint, columns)
+    data += (getattr(service, 'name', ''), service.type)
+    return column_headers, data
 
 
 class AddProjectToEndpoint(command.Command):
@@ -44,15 +64,13 @@ class AddProjectToEndpoint(command.Comma
             'endpoint',
             metavar='<endpoint>',
             help=_(
-                'Endpoint to associate with ' 'specified project (name or ID)'
+                'Endpoint to associate with specified project (name or ID)'
             ),
         )
         parser.add_argument(
             'project',
             metavar='<project>',
-            help=_(
-                'Project to associate with ' 'specified endpoint name or ID)'
-            ),
+            help=_('Project to associate with specified endpoint name or ID)'),
         )
         common.add_project_domain_option_to_parser(parser)
         return parser
@@ -114,23 +132,23 @@ class CreateEndpoint(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
-        service = common.find_service(identity_client, parsed_args.service)
+        identity_client = self.app.client_manager.sdk_connection.identity
+        service = common.find_service_sdk(identity_client, parsed_args.service)
+
+        kwargs = {}
+
+        kwargs['service_id'] = service.id
+        kwargs['url'] = parsed_args.url
+        kwargs['interface'] = parsed_args.interface
+        kwargs['is_enabled'] = parsed_args.enabled
+
+        if parsed_args.region:
+            region = identity_client.get_region(parsed_args.region)
+            kwargs['region_id'] = region.id
+
+        endpoint = identity_client.create_endpoint(**kwargs)
 
-        endpoint = identity_client.endpoints.create(
-            service=service.id,
-            url=parsed_args.url,
-            interface=parsed_args.interface,
-            region=parsed_args.region,
-            enabled=parsed_args.enabled,
-        )
-
-        info = {}
-        endpoint._info.pop('links')
-        info.update(endpoint._info)
-        info['service_name'] = get_service_name(service)
-        info['service_type'] = service.type
-        return zip(*sorted(info.items()))
+        return _format_endpoint(endpoint, service=service)
 
 
 class DeleteEndpoint(command.Command):
@@ -147,14 +165,12 @@ class DeleteEndpoint(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
         result = 0
         for i in parsed_args.endpoint:
             try:
-                endpoint_id = utils.find_resource(
-                    identity_client.endpoints, i
-                ).id
-                identity_client.endpoints.delete(endpoint_id)
+                endpoint_id = identity_client.find_endpoint(i).id
+                identity_client.delete_endpoint(endpoint_id)
             except Exception as e:
                 result += 1
                 LOG.error(
@@ -167,9 +183,10 @@ class DeleteEndpoint(command.Command):
 
         if result > 0:
             total = len(parsed_args.endpoint)
-            msg = _(
-                "%(result)s of %(total)s endpoints failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s endpoints failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -209,28 +226,24 @@ class ListEndpoint(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
         endpoint = None
         if parsed_args.endpoint:
-            endpoint = utils.find_resource(
-                identity_client.endpoints, parsed_args.endpoint
-            )
+            endpoint = identity_client.find_endpoint(parsed_args.endpoint)
         project = None
         if parsed_args.project:
-            project = common.find_project(
-                identity_client,
+            project = identity_client.find_project(
                 parsed_args.project,
                 parsed_args.project_domain,
             )
 
         if endpoint:
-            columns = ('ID', 'Name')
-            data = identity_client.endpoint_filter.list_projects_for_endpoint(
-                endpoint=endpoint.id
-            )
+            column_headers: tuple[str, ...] = ('ID', 'Name')
+            columns: tuple[str, ...] = ('id', 'name')
+            data = identity_client.endpoint_projects(endpoint=endpoint.id)
         else:
-            columns = (
+            column_headers = (
                 'ID',
                 'Region',
                 'Service Name',
@@ -239,37 +252,41 @@ class ListEndpoint(command.Lister):
                 'Interface',
                 'URL',
             )
+            columns = (
+                'id',
+                'region_id',
+                'service_name',
+                'service_type',
+                'is_enabled',
+                'interface',
+                'url',
+            )
             kwargs = {}
             if parsed_args.service:
-                service = common.find_service(
+                service = common.find_service_sdk(
                     identity_client, parsed_args.service
                 )
-                kwargs['service'] = service.id
+                kwargs['service_id'] = service.id
             if parsed_args.interface:
                 kwargs['interface'] = parsed_args.interface
             if parsed_args.region:
-                kwargs['region'] = parsed_args.region
+                region = identity_client.get_region(parsed_args.region)
+                kwargs['region_id'] = region.id
 
             if project:
-                data = (
-                    identity_client.endpoint_filter.list_endpoints_for_project(
-                        project=project.id
-                    )
+                data = list(
+                    identity_client.project_endpoints(project=project.id)
                 )
             else:
-                data = identity_client.endpoints.list(**kwargs)
-
-            service_list = identity_client.services.list()
+                data = list(identity_client.endpoints(**kwargs))
 
             for ep in data:
-                service = common.find_service_in_list(
-                    service_list, ep.service_id
-                )
-                ep.service_name = get_service_name(service)
+                service = identity_client.find_service(ep.service_id)
+                ep.service_name = getattr(service, 'name', '')
                 ep.service_type = service.type
 
         return (
-            columns,
+            column_headers,
             (
                 utils.get_item_properties(
                     s,
@@ -290,14 +307,14 @@ class RemoveProjectFromEndpoint(command.
             'endpoint',
             metavar='<endpoint>',
             help=_(
-                'Endpoint to dissociate from ' 'specified project (name or ID)'
+                'Endpoint to dissociate from specified project (name or ID)'
             ),
         )
         parser.add_argument(
             'project',
             metavar='<project>',
             help=_(
-                'Project to dissociate from ' 'specified endpoint name or ID)'
+                'Project to dissociate from specified endpoint name or ID)'
             ),
         )
         common.add_project_domain_option_to_parser(parser)
@@ -364,28 +381,34 @@ class SetEndpoint(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
-        endpoint = utils.find_resource(
-            identity_client.endpoints, parsed_args.endpoint
-        )
+        identity_client = self.app.client_manager.sdk_connection.identity
+        endpoint = identity_client.find_endpoint(parsed_args.endpoint)
+
+        kwargs = {}
 
-        service_id = None
         if parsed_args.service:
-            service = common.find_service(identity_client, parsed_args.service)
-            service_id = service.id
-        enabled = None
+            service = common.find_service_sdk(
+                identity_client, parsed_args.service
+            )
+            kwargs['service_id'] = service.id
+
         if parsed_args.enabled:
-            enabled = True
+            kwargs['is_enabled'] = True
         if parsed_args.disabled:
-            enabled = False
+            kwargs['is_enabled'] = False
 
-        identity_client.endpoints.update(
+        if parsed_args.url:
+            kwargs['url'] = parsed_args.url
+
+        if parsed_args.interface:
+            kwargs['interface'] = parsed_args.interface
+
+        if parsed_args.region:
+            kwargs['region_id'] = parsed_args.region
+
+        identity_client.update_endpoint(
             endpoint.id,
-            service=service_id,
-            url=parsed_args.url,
-            interface=parsed_args.interface,
-            region=parsed_args.region,
-            enabled=enabled,
+            **kwargs,
         )
 
 
@@ -405,16 +428,9 @@ class ShowEndpoint(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
-        endpoint = utils.find_resource(
-            identity_client.endpoints, parsed_args.endpoint
-        )
+        identity_client = self.app.client_manager.sdk_connection.identity
+        endpoint = identity_client.find_endpoint(parsed_args.endpoint)
+
+        service = common.find_service_sdk(identity_client, endpoint.service_id)
 
-        service = common.find_service(identity_client, endpoint.service_id)
-
-        info = {}
-        endpoint._info.pop('links')
-        info.update(endpoint._info)
-        info['service_name'] = get_service_name(service)
-        info['service_type'] = service.type
-        return zip(*sorted(info.items()))
+        return _format_endpoint(endpoint, service)
diff -pruN 7.4.0-3/openstackclient/identity/v3/endpoint_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/endpoint_group.py
--- 7.4.0-3/openstackclient/identity/v3/endpoint_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/endpoint_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -168,7 +168,7 @@ class DeleteEndpointGroup(command.Comman
         if result > 0:
             total = len(parsed_args.endpointgroup)
             msg = _(
-                "%(result)s of %(total)s endpointgroups failed " "to delete."
+                "%(result)s of %(total)s endpointgroups failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/group.py
--- 7.4.0-3/openstackclient/identity/v3/group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/group.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,7 +17,7 @@
 
 import logging
 
-from keystoneauth1 import exceptions as ks_exc
+from openstack import exceptions as sdk_exc
 from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
@@ -29,6 +29,25 @@ from openstackclient.identity import com
 LOG = logging.getLogger(__name__)
 
 
+def _format_group(group):
+    columns = (
+        'description',
+        'domain_id',
+        'id',
+        'name',
+    )
+    column_headers = (
+        'description',
+        'domain_id',
+        'id',
+        'name',
+    )
+    return (
+        column_headers,
+        utils.get_item_properties(group, columns),
+    )
+
+
 class AddUserToGroup(command.Command):
     _description = _("Add user to group")
 
@@ -53,19 +72,19 @@ class AddUserToGroup(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
-        group_id = common.find_group(
+        group_id = common.find_group_id_sdk(
             identity_client, parsed_args.group, parsed_args.group_domain
-        ).id
+        )
 
         result = 0
         for i in parsed_args.user:
             try:
-                user_id = common.find_user(
+                user_id = common.find_user_id_sdk(
                     identity_client, i, parsed_args.user_domain
-                ).id
-                identity_client.users.add_to_group(user_id, group_id)
+                )
+                identity_client.add_user_to_group(user_id, group_id)
             except Exception as e:
                 result += 1
                 msg = _("%(user)s not added to group %(group)s: %(e)s") % {
@@ -109,32 +128,41 @@ class CheckUserInGroup(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
-        user_id = common.find_user(
-            identity_client, parsed_args.user, parsed_args.user_domain
-        ).id
-        group_id = common.find_group(
-            identity_client, parsed_args.group, parsed_args.group_domain
-        ).id
+        user_id = common.find_user_id_sdk(
+            identity_client,
+            parsed_args.user,
+            parsed_args.user_domain,
+            validate_actor_existence=False,
+        )
+        group_id = common.find_group_id_sdk(
+            identity_client,
+            parsed_args.group,
+            parsed_args.group_domain,
+            validate_actor_existence=False,
+        )
 
+        user_in_group = False
         try:
-            identity_client.users.check_in_group(user_id, group_id)
-        except ks_exc.http.HTTPClientError as e:
-            if e.http_status == 403 or e.http_status == 404:
-                msg = _("%(user)s not in group %(group)s\n") % {
-                    'user': parsed_args.user,
-                    'group': parsed_args.group,
-                }
-                self.app.stderr.write(msg)
-            else:
-                raise e
-        else:
+            user_in_group = identity_client.check_user_in_group(
+                user_id, group_id
+            )
+        except sdk_exc.ForbiddenException:
+            # Assume False if forbidden
+            pass
+        if user_in_group:
             msg = _("%(user)s in group %(group)s\n") % {
                 'user': parsed_args.user,
                 'group': parsed_args.group,
             }
             self.app.stdout.write(msg)
+        else:
+            msg = _("%(user)s not in group %(group)s\n") % {
+                'user': parsed_args.user,
+                'group': parsed_args.group,
+            }
+            self.app.stderr.write(msg)
 
 
 class CreateGroup(command.ShowOne):
@@ -165,29 +193,33 @@ class CreateGroup(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
-        domain = None
+        kwargs = {}
+        if parsed_args.name:
+            kwargs['name'] = parsed_args.name
+        if parsed_args.description:
+            kwargs['description'] = parsed_args.description
         if parsed_args.domain:
-            domain = common.find_domain(identity_client, parsed_args.domain).id
+            kwargs['domain_id'] = common.find_domain_id_sdk(
+                identity_client, parsed_args.domain
+            )
 
         try:
-            group = identity_client.groups.create(
-                name=parsed_args.name,
-                domain=domain,
-                description=parsed_args.description,
-            )
-        except ks_exc.Conflict:
+            group = identity_client.create_group(**kwargs)
+        except sdk_exc.ConflictException:
             if parsed_args.or_show:
-                group = utils.find_resource(
-                    identity_client.groups, parsed_args.name, domain_id=domain
-                )
+                if parsed_args.domain:
+                    group = identity_client.find_group(
+                        parsed_args.name, domain_id=parsed_args.domain
+                    )
+                else:
+                    group = identity_client.find_group(parsed_args.name)
                 LOG.info(_('Returning existing group %s'), group.name)
             else:
                 raise
 
-        group._info.pop('links')
-        return zip(*sorted(group._info.items()))
+        return _format_group(group)
 
 
 class DeleteGroup(command.Command):
@@ -209,15 +241,15 @@ class DeleteGroup(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
         errors = 0
         for group in parsed_args.groups:
             try:
-                group_obj = common.find_group(
+                group_id = common.find_group_id_sdk(
                     identity_client, group, parsed_args.domain
                 )
-                identity_client.groups.delete(group_obj.id)
+                identity_client.delete_group(group_id)
             except Exception as e:
                 errors += 1
                 LOG.error(
@@ -230,7 +262,7 @@ class DeleteGroup(command.Command):
 
         if errors > 0:
             total = len(parsed_args.groups)
-            msg = _("%(errors)s of %(total)s groups failed " "to delete.") % {
+            msg = _("%(errors)s of %(total)s groups failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
@@ -262,30 +294,37 @@ class ListGroup(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
         domain = None
         if parsed_args.domain:
-            domain = common.find_domain(identity_client, parsed_args.domain).id
+            domain = common.find_domain_id_sdk(
+                identity_client, parsed_args.domain
+            )
 
+        data = []
         if parsed_args.user:
-            user = common.find_user(
+            user = common.find_user_id_sdk(
                 identity_client,
                 parsed_args.user,
                 parsed_args.user_domain,
-            ).id
+            )
+            if domain:
+                # NOTE(0weng): The API doesn't actually support filtering additionally by domain_id,
+                # so this doesn't really do anything.
+                data = identity_client.user_groups(user, domain_id=domain)
+            else:
+                data = identity_client.user_groups(user)
         else:
-            user = None
+            if domain:
+                data = identity_client.groups(domain_id=domain)
+            else:
+                data = identity_client.groups()
 
         # List groups
+        columns: tuple[str, ...] = ('ID', 'Name')
         if parsed_args.long:
-            columns = ('ID', 'Name', 'Domain ID', 'Description')
-        else:
-            columns = ('ID', 'Name')
-        data = identity_client.groups.list(
-            domain=domain,
-            user=user,
-        )
+            columns += ('Domain ID', 'Description')
 
         return (
             columns,
@@ -324,19 +363,19 @@ class RemoveUserFromGroup(command.Comman
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
-        group_id = common.find_group(
+        group_id = common.find_group_id_sdk(
             identity_client, parsed_args.group, parsed_args.group_domain
-        ).id
+        )
 
         result = 0
         for i in parsed_args.user:
             try:
-                user_id = common.find_user(
+                user_id = common.find_user_id_sdk(
                     identity_client, i, parsed_args.user_domain
-                ).id
-                identity_client.users.remove_from_group(user_id, group_id)
+                )
+                identity_client.remove_user_from_group(user_id, group_id)
             except Exception as e:
                 result += 1
                 msg = _("%(user)s not removed from group %(group)s: %(e)s") % {
@@ -388,8 +427,8 @@ class SetGroup(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
-        group = common.find_group(
+        identity_client = self.app.client_manager.sdk_connection.identity
+        group = common.find_group_id_sdk(
             identity_client, parsed_args.group, parsed_args.domain
         )
         kwargs = {}
@@ -398,7 +437,7 @@ class SetGroup(command.Command):
         if parsed_args.description:
             kwargs['description'] = parsed_args.description
 
-        identity_client.groups.update(group.id, **kwargs)
+        identity_client.update_group(group, **kwargs)
 
 
 class ShowGroup(command.ShowOne):
@@ -419,13 +458,18 @@ class ShowGroup(command.ShowOne):
         return parser
 
     def take_action(self, parsed_args):
-        identity_client = self.app.client_manager.identity
+        identity_client = self.app.client_manager.sdk_connection.identity
 
-        group = common.find_group(
-            identity_client,
-            parsed_args.group,
-            domain_name_or_id=parsed_args.domain,
-        )
+        if parsed_args.domain:
+            domain = common.find_domain_id_sdk(
+                identity_client, parsed_args.domain
+            )
+            group = identity_client.find_group(
+                parsed_args.group, domain_id=domain, ignore_missing=False
+            )
+        else:
+            group = identity_client.find_group(
+                parsed_args.group, ignore_missing=False
+            )
 
-        group._info.pop('links')
-        return zip(*sorted(group._info.items()))
+        return _format_group(group)
diff -pruN 7.4.0-3/openstackclient/identity/v3/identity_provider.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/identity_provider.py
--- 7.4.0-3/openstackclient/identity/v3/identity_provider.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/identity_provider.py	2025-07-07 22:41:56.000000000 +0000
@@ -174,8 +174,7 @@ class DeleteIdentityProvider(command.Com
         if result > 0:
             total = len(parsed_args.identity_provider)
             msg = _(
-                "%(result)s of %(total)s identity providers failed"
-                " to delete."
+                "%(result)s of %(total)s identity providers failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/limit.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/limit.py
--- 7.4.0-3/openstackclient/identity/v3/limit.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/limit.py	2025-07-07 22:41:56.000000000 +0000
@@ -77,8 +77,7 @@ class CreateLimit(command.ShowOne):
         )
         region = None
         if parsed_args.region:
-            val = getattr(parsed_args, 'region', None)
-            if 'None' not in val:
+            if 'None' not in parsed_args.region:
                 # NOTE (vishakha): Due to bug #1799153 and for any another
                 # related case where GET resource API does not support the
                 # filter by name, osc_lib.utils.find_resource() method cannot
@@ -149,11 +148,7 @@ class ListLimit(command.Lister):
             )
         region = None
         if parsed_args.region:
-            region = utils.find_resource(
-                identity_client.regions, parsed_args.region
-            )
-            val = getattr(parsed_args, 'region', None)
-            if 'None' not in val:
+            if 'None' not in parsed_args.region:
                 # NOTE (vishakha): Due to bug #1799153 and for any another
                 # related case where GET resource API does not support the
                 # filter by name, osc_lib.utils.find_resource() method cannot
@@ -281,13 +276,13 @@ class DeleteLimit(command.Command):
             except Exception as e:
                 errors += 1
                 LOG.error(
-                    _("Failed to delete limit with ID " "'%(id)s': %(e)s"),
+                    _("Failed to delete limit with ID '%(id)s': %(e)s"),
                     {'id': limit_id, 'e': e},
                 )
 
         if errors > 0:
             total = len(parsed_args.limit_id)
-            msg = _("%(errors)s of %(total)s limits failed to " "delete.") % {
+            msg = _("%(errors)s of %(total)s limits failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
diff -pruN 7.4.0-3/openstackclient/identity/v3/mapping.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/mapping.py
--- 7.4.0-3/openstackclient/identity/v3/mapping.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/mapping.py	2025-07-07 22:41:56.000000000 +0000
@@ -161,9 +161,10 @@ class DeleteMapping(command.Command):
 
         if result > 0:
             total = len(parsed_args.mapping)
-            msg = _(
-                "%(result)s of %(total)s mappings failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s mappings failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/policy.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/policy.py
--- 7.4.0-3/openstackclient/identity/v3/policy.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/policy.py	2025-07-07 22:41:56.000000000 +0000
@@ -92,9 +92,7 @@ class DeletePolicy(command.Command):
 
         if result > 0:
             total = len(parsed_args.policy)
-            msg = _(
-                "%(result)s of %(total)s policies failed " "to delete."
-            ) % {
+            msg = _("%(result)s of %(total)s policies failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -115,12 +113,11 @@ class ListPolicy(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('ID', 'Type')
+        column_headers: tuple[str, ...] = columns
         if parsed_args.long:
-            columns = ('ID', 'Type', 'Blob')
-            column_headers = ('ID', 'Type', 'Rules')
-        else:
-            columns = ('ID', 'Type')
-            column_headers = columns
+            columns += ('Blob',)
+            column_headers += ('Rules',)
         data = self.app.client_manager.identity.policies.list()
         return (
             column_headers,
diff -pruN 7.4.0-3/openstackclient/identity/v3/project.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/project.py
--- 7.4.0-3/openstackclient/identity/v3/project.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/project.py	2025-07-07 22:41:56.000000000 +0000
@@ -59,17 +59,22 @@ class CreateProject(command.ShowOne):
         enable_group.add_argument(
             '--enable',
             action='store_true',
+            dest='enabled',
+            default=True,
             help=_('Enable project'),
         )
         enable_group.add_argument(
             '--disable',
-            action='store_true',
+            action='store_false',
+            dest='enabled',
+            default=True,
             help=_('Disable project'),
         )
         parser.add_argument(
             '--property',
             metavar='<key=value>',
             action=parseractions.KeyValueAction,
+            dest='properties',
             help=_(
                 'Add a property to <name> '
                 '(repeat option to set multiple properties)'
@@ -98,15 +103,9 @@ class CreateProject(command.ShowOne):
                 parsed_args.parent,
             ).id
 
-        enabled = True
-        if parsed_args.disable:
-            enabled = False
-
-        options = common.get_immutable_options(parsed_args)
-
         kwargs = {}
-        if parsed_args.property:
-            kwargs = parsed_args.property.copy()
+        if parsed_args.properties:
+            kwargs = parsed_args.properties.copy()
         if 'is_domain' in kwargs.keys():
             if kwargs['is_domain'].lower() == "true":
                 kwargs['is_domain'] = True
@@ -117,13 +116,17 @@ class CreateProject(command.ShowOne):
 
         kwargs['tags'] = list(set(parsed_args.tags))
 
+        options = {}
+        if parsed_args.immutable is not None:
+            options['immutable'] = parsed_args.immutable
+
         try:
             project = identity_client.projects.create(
                 name=parsed_args.name,
                 domain=domain,
                 parent=parent,
                 description=parsed_args.description,
-                enabled=enabled,
+                enabled=parsed_args.enabled,
                 options=options,
                 **kwargs,
             )
@@ -190,9 +193,10 @@ class DeleteProject(command.Command):
 
         if errors > 0:
             total = len(parsed_args.projects)
-            msg = _(
-                "%(errors)s of %(total)s projects failed " "to delete."
-            ) % {'errors': errors, 'total': total}
+            msg = _("%(errors)s of %(total)s projects failed to delete.") % {
+                'errors': errors,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -239,15 +243,28 @@ class ListProject(command.Lister):
                 'keys and directions.'
             ),
         )
+        parser.add_argument(
+            '--enabled',
+            action='store_true',
+            dest='is_enabled',
+            default=None,
+            help=_('List only enabled projects'),
+        )
+        parser.add_argument(
+            '--disabled',
+            action='store_false',
+            dest='is_enabled',
+            default=None,
+            help=_('List only disabled projects'),
+        )
         tag.add_tag_filtering_option_to_parser(parser, _('projects'))
         return parser
 
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.identity
+        columns: tuple[str, ...] = ('ID', 'Name')
         if parsed_args.long:
-            columns = ('ID', 'Name', 'Domain ID', 'Description', 'Enabled')
-        else:
-            columns = ('ID', 'Name')
+            columns += ('Domain ID', 'Description', 'Enabled')
         kwargs = {}
 
         domain_id = None
@@ -277,6 +294,9 @@ class ListProject(command.Lister):
 
             kwargs['user'] = user_id
 
+        if parsed_args.is_enabled is not None:
+            kwargs['is_enabled'] = parsed_args.is_enabled
+
         tag.get_tag_filtering_args(parsed_args, kwargs)
 
         if parsed_args.my_projects:
@@ -339,16 +359,21 @@ class SetProject(command.Command):
         enable_group.add_argument(
             '--enable',
             action='store_true',
+            dest='enabled',
+            default=None,
             help=_('Enable project'),
         )
         enable_group.add_argument(
             '--disable',
-            action='store_true',
+            action='store_false',
+            dest='enabled',
+            default=None,
             help=_('Disable project'),
         )
         parser.add_argument(
             '--property',
             metavar='<key=value>',
+            dest='properties',
             action=parseractions.KeyValueAction,
             help=_(
                 'Set a property on <project> '
@@ -371,15 +396,12 @@ class SetProject(command.Command):
             kwargs['name'] = parsed_args.name
         if parsed_args.description:
             kwargs['description'] = parsed_args.description
-        if parsed_args.enable:
-            kwargs['enabled'] = True
-        if parsed_args.disable:
-            kwargs['enabled'] = False
-        options = common.get_immutable_options(parsed_args)
-        if options:
-            kwargs['options'] = options
-        if parsed_args.property:
-            kwargs.update(parsed_args.property)
+        if parsed_args.enabled is not None:
+            kwargs['enabled'] = parsed_args.enabled
+        if parsed_args.immutable is not None:
+            kwargs['options'] = {'immutable': parsed_args.immutable}
+        if parsed_args.properties:
+            kwargs.update(parsed_args.properties)
         tag.update_tags_in_args(parsed_args, project, kwargs)
 
         identity_client.projects.update(project.id, **kwargs)
diff -pruN 7.4.0-3/openstackclient/identity/v3/region.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/region.py
--- 7.4.0-3/openstackclient/identity/v3/region.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/region.py	2025-07-07 22:41:56.000000000 +0000
@@ -92,16 +92,13 @@ class DeleteRegion(command.Command):
             except Exception as e:
                 result += 1
                 LOG.error(
-                    _(
-                        "Failed to delete region with "
-                        "ID '%(region)s': %(e)s"
-                    ),
+                    _("Failed to delete region with ID '%(region)s': %(e)s"),
                     {'region': i, 'e': e},
                 )
 
         if result > 0:
             total = len(parsed_args.region)
-            msg = _("%(result)s of %(total)s regions failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s regions failed to delete.") % {
                 'result': result,
                 'total': total,
             }
diff -pruN 7.4.0-3/openstackclient/identity/v3/registered_limit.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/registered_limit.py
--- 7.4.0-3/openstackclient/identity/v3/registered_limit.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/registered_limit.py	2025-07-07 22:41:56.000000000 +0000
@@ -68,8 +68,7 @@ class CreateRegisteredLimit(command.Show
         )
         region = None
         if parsed_args.region:
-            val = getattr(parsed_args, 'region', None)
-            if 'None' not in val:
+            if 'None' not in parsed_args.region:
                 # NOTE (vishakha): Due to bug #1799153 and for any another
                 # related case where GET resource API does not support the
                 # filter by name, osc_lib.utils.find_resource() method cannot
@@ -137,8 +136,7 @@ class DeleteRegisteredLimit(command.Comm
         if errors > 0:
             total = len(parsed_args.registered_limit_id)
             msg = _(
-                "%(errors)s of %(total)s registered limits failed to "
-                "delete."
+                "%(errors)s of %(total)s registered limits failed to delete."
             ) % {'errors': errors, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -176,8 +174,7 @@ class ListRegisteredLimit(command.Lister
             )
         region = None
         if parsed_args.region:
-            val = getattr(parsed_args, 'region', None)
-            if 'None' not in val:
+            if 'None' not in parsed_args.region:
                 # NOTE (vishakha): Due to bug #1799153 and for any another
                 # related case where GET resource API does not support the
                 # filter by name, osc_lib.utils.find_resource() method cannot
@@ -281,8 +278,7 @@ class SetRegisteredLimit(command.ShowOne
 
         region = None
         if parsed_args.region:
-            val = getattr(parsed_args, 'region', None)
-            if 'None' not in val:
+            if 'None' not in parsed_args.region:
                 # NOTE (vishakha): Due to bug #1799153 and for any another
                 # related case where GET resource API does not support the
                 # filter by name, osc_lib.utils.find_resource() method cannot
diff -pruN 7.4.0-3/openstackclient/identity/v3/role.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/role.py
--- 7.4.0-3/openstackclient/identity/v3/role.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/role.py	2025-07-07 22:41:56.000000000 +0000
@@ -334,9 +334,12 @@ class CreateRole(command.ShowOne):
 
         if parsed_args.name:
             create_kwargs['name'] = parsed_args.name
+
         if parsed_args.description:
             create_kwargs['description'] = parsed_args.description
-        create_kwargs['options'] = common.get_immutable_options(parsed_args)
+
+        if parsed_args.immutable is not None:
+            create_kwargs['options'] = {"immutable": parsed_args.immutable}
 
         try:
             role = identity_client.create_role(**create_kwargs)
@@ -402,7 +405,7 @@ class DeleteRole(command.Command):
 
         if errors > 0:
             total = len(parsed_args.roles)
-            msg = _("%(errors)s of %(total)s roles failed " "to delete.") % {
+            msg = _("%(errors)s of %(total)s roles failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
@@ -428,28 +431,27 @@ class ListRole(command.Lister):
             domain = identity_client.find_domain(
                 name_or_id=parsed_args.domain,
             )
-            columns = ('ID', 'Name', 'Domain')
             data = identity_client.roles(domain_id=domain.id)
+            return (
+                ('ID', 'Name', 'Domain'),
+                (
+                    utils.get_item_properties(s, ('id', 'name'))
+                    + (domain.name,)
+                    for s in data
+                ),
+            )
+
         else:
-            columns = ('ID', 'Name')
             data = identity_client.roles()
-
-        return (
-            columns,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                    formatters={'Domain': lambda _: domain.name},
-                )
-                for s in data
-            ),
-        )
+            return (
+                ('ID', 'Name'),
+                (utils.get_item_properties(s, ('id', 'name')) for s in data),
+            )
 
 
 class RemoveRole(command.Command):
     _description = _(
-        "Removes a role assignment from system/domain/project : " "user/group"
+        "Removes a role assignment from system/domain/project : user/group"
     )
 
     def get_parser(self, prog_name):
@@ -586,7 +588,9 @@ class SetRole(command.Command):
             )
             update_kwargs["domain_id"] = domain_id
 
-        update_kwargs["options"] = common.get_immutable_options(parsed_args)
+        if parsed_args.immutable is not None:
+            update_kwargs["options"] = {"immutable": parsed_args.immutable}
+
         role = _find_sdk_id(
             identity_client.find_role,
             name_or_id=parsed_args.role,
diff -pruN 7.4.0-3/openstackclient/identity/v3/service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/service.py
--- 7.4.0-3/openstackclient/identity/v3/service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/service.py	2025-07-07 22:41:56.000000000 +0000
@@ -135,9 +135,10 @@ class DeleteService(command.Command):
 
         if result > 0:
             total = len(parsed_args.service)
-            msg = _(
-                "%(result)s of %(total)s services failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s services failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -157,12 +158,11 @@ class ListService(command.Lister):
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.sdk_connection.identity
 
+        columns: tuple[str, ...] = ('id', 'name', 'type')
+        column_headers: tuple[str, ...] = ('ID', 'Name', 'Type')
         if parsed_args.long:
-            columns = ('id', 'name', 'type', 'description', 'is_enabled')
-            column_headers = ('ID', 'Name', 'Type', 'Description', 'Enabled')
-        else:
-            columns = ('id', 'name', 'type')
-            column_headers = ('ID', 'Name', 'Type')
+            columns += ('description', 'is_enabled')
+            column_headers += ('Description', 'Enabled')
 
         data = identity_client.services()
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/service_provider.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/service_provider.py
--- 7.4.0-3/openstackclient/identity/v3/service_provider.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/service_provider.py	2025-07-07 22:41:56.000000000 +0000
@@ -77,8 +77,7 @@ class CreateServiceProvider(command.Show
             metavar='<sp-url>',
             required=True,
             help=_(
-                'A service URL where SAML assertions are being sent '
-                '(required)'
+                'A service URL where SAML assertions are being sent (required)'
             ),
         )
 
@@ -155,8 +154,7 @@ class DeleteServiceProvider(command.Comm
         if result > 0:
             total = len(parsed_args.service_provider)
             msg = _(
-                "%(result)s of %(total)s service providers failed"
-                " to delete."
+                "%(result)s of %(total)s service providers failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -204,8 +202,7 @@ class SetServiceProvider(command.ShowOne
             '--auth-url',
             metavar='<auth-url>',
             help=_(
-                'New Authentication URL of remote '
-                'federated service provider'
+                'New Authentication URL of remote federated service provider'
             ),
         )
 
diff -pruN 7.4.0-3/openstackclient/identity/v3/tag.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/tag.py
--- 7.4.0-3/openstackclient/identity/v3/tag.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/tag.py	2025-07-07 22:41:56.000000000 +0000
@@ -83,7 +83,7 @@ def add_tag_option_to_parser_for_create(
         metavar='<tag>',
         default=[],
         help=_(
-            'Tag to be added to the %s ' '(repeat option to set multiple tags)'
+            'Tag to be added to the %s (repeat option to set multiple tags)'
         )
         % resource_name,
     )
@@ -97,7 +97,7 @@ def add_tag_option_to_parser_for_set(par
         metavar='<tag>',
         default=[],
         help=_(
-            'Tag to be added to the %s ' '(repeat option to set multiple tags)'
+            'Tag to be added to the %s (repeat option to set multiple tags)'
         )
         % resource_name,
     )
diff -pruN 7.4.0-3/openstackclient/identity/v3/token.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/token.py
--- 7.4.0-3/openstackclient/identity/v3/token.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/token.py	2025-07-07 22:41:56.000000000 +0000
@@ -136,8 +136,7 @@ class CreateRequestToken(command.ShowOne
             '--project',
             metavar='<project>',
             help=_(
-                'Project that consumer wants to access (name or ID)'
-                ' (required)'
+                'Project that consumer wants to access (name or ID) (required)'
             ),
             required=True,
         )
diff -pruN 7.4.0-3/openstackclient/identity/v3/trust.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/trust.py
--- 7.4.0-3/openstackclient/identity/v3/trust.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/trust.py	2025-07-07 22:41:56.000000000 +0000
@@ -123,37 +123,67 @@ class CreateTrust(command.ShowOne):
         # pointless, and trusts are immutable, so let's enforce it at the
         # client level.
         try:
-            trustor_id = identity_client.find_user(
-                parsed_args.trustor, parsed_args.trustor_domain
-            ).id
-            kwargs['trustor_id'] = trustor_id
+            if parsed_args.trustor_domain:
+                trustor_domain_id = identity_client.find_domain(
+                    parsed_args.trustor_domain, ignore_missing=False
+                ).id
+                trustor_id = identity_client.find_user(
+                    parsed_args.trustor,
+                    ignore_missing=False,
+                    domain_id=trustor_domain_id,
+                ).id
+            else:
+                trustor_id = identity_client.find_user(
+                    parsed_args.trustor, ignore_missing=False
+                ).id
+            kwargs['trustor_user_id'] = trustor_id
         except sdk_exceptions.ForbiddenException:
-            kwargs['trustor_id'] = parsed_args.trustor
+            kwargs['trustor_user_id'] = parsed_args.trustor
 
         try:
-            trustee_id = identity_client.find_user(
-                parsed_args.trustee, parsed_args.trustee_domain
-            ).id
-            kwargs['trustee_id'] = trustee_id
+            if parsed_args.trustee_domain:
+                trustee_domain_id = identity_client.find_domain(
+                    parsed_args.trustee_domain, ignore_missing=False
+                ).id
+                trustee_id = identity_client.find_user(
+                    parsed_args.trustee,
+                    ignore_missing=False,
+                    domain_id=trustee_domain_id,
+                ).id
+            else:
+                trustee_id = identity_client.find_user(
+                    parsed_args.trustee, ignore_missing=False
+                ).id
+            kwargs['trustee_user_id'] = trustee_id
         except sdk_exceptions.ForbiddenException:
-            kwargs['trustee_id'] = parsed_args.trustee
+            kwargs['trustee_user_id'] = parsed_args.trustee
 
         try:
-            project_id = identity_client.find_project(
-                parsed_args.project, parsed_args.project_domain
-            ).id
+            if parsed_args.project_domain:
+                project_domain_id = identity_client.find_domain(
+                    parsed_args.project_domain, ignore_missing=False
+                ).id
+                project_id = identity_client.find_project(
+                    parsed_args.project,
+                    ignore_missing=False,
+                    domain_id=project_domain_id,
+                ).id
+            else:
+                project_id = identity_client.find_project(
+                    parsed_args.project, ignore_missing=False
+                ).id
             kwargs['project_id'] = project_id
         except sdk_exceptions.ForbiddenException:
             kwargs['project_id'] = parsed_args.project
 
-        role_ids = []
+        roles = []
         for role in parsed_args.roles:
             try:
                 role_id = identity_client.find_role(role).id
             except sdk_exceptions.ForbiddenException:
                 role_id = role
-            role_ids.append(role_id)
-        kwargs['roles'] = role_ids
+            roles.append({"id": role_id})
+        kwargs['roles'] = roles
 
         if parsed_args.expiration:
             expires_at = datetime.datetime.strptime(
@@ -161,8 +191,7 @@ class CreateTrust(command.ShowOne):
             )
             kwargs['expires_at'] = expires_at
 
-        if parsed_args.is_impersonation:
-            kwargs['is_impersonation'] = parsed_args.is_impersonation
+        kwargs['impersonation'] = bool(parsed_args.is_impersonation)
 
         trust = identity_client.create_trust(**kwargs)
 
@@ -204,7 +233,7 @@ class DeleteTrust(command.Command):
 
         if errors > 0:
             total = len(parsed_args.trust)
-            msg = _("%(errors)s of %(total)s trusts failed " "to delete.") % {
+            msg = _("%(errors)s of %(total)s trusts failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
@@ -289,9 +318,19 @@ class ListTrust(command.Lister):
             trustor = None
             if parsed_args.trustor:
                 try:
-                    trustor_id = identity_client.find_user(
-                        parsed_args.trustor, parsed_args.trustor_domain
-                    ).id
+                    if parsed_args.trustor_domain:
+                        trustor_domain_id = identity_client.find_domain(
+                            parsed_args.trustor_domain, ignore_missing=False
+                        ).id
+                        trustor_id = identity_client.find_user(
+                            parsed_args.trustor,
+                            ignore_missing=False,
+                            domain_id=trustor_domain_id,
+                        ).id
+                    else:
+                        trustor_id = identity_client.find_user(
+                            parsed_args.trustor, ignore_missing=False
+                        ).id
                     trustor = trustor_id
                 except sdk_exceptions.ForbiddenException:
                     trustor = parsed_args.trustor
@@ -299,9 +338,19 @@ class ListTrust(command.Lister):
             trustee = None
             if parsed_args.trustee:
                 try:
-                    trustee_id = identity_client.find_user(
-                        parsed_args.trustee, parsed_args.trustee_domain
-                    ).id
+                    if parsed_args.trustee_domain:
+                        trustee_domain_id = identity_client.find_domain(
+                            parsed_args.trustee_domain, ignore_missing=False
+                        ).id
+                        trustee_id = identity_client.find_user(
+                            parsed_args.trustee,
+                            ignore_missing=False,
+                            domain_id=trustee_domain_id,
+                        ).id
+                    else:
+                        trustee_id = identity_client.find_user(
+                            parsed_args.trustee, ignore_missing=False
+                        ).id
                     trustee = trustee_id
                 except sdk_exceptions.ForbiddenException:
                     trustee = parsed_args.trustee
diff -pruN 7.4.0-3/openstackclient/identity/v3/user.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/user.py
--- 7.4.0-3/openstackclient/identity/v3/user.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/identity/v3/user.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@
 
 import copy
 import logging
+import typing as ty
 
 from openstack import exceptions as sdk_exc
 from osc_lib.command import command
@@ -40,6 +41,7 @@ def _format_user(user):
         'name',
         'description',
         'password_expires_at',
+        'options',
     )
     column_headers = (
         'default_project_id',
@@ -50,6 +52,7 @@ def _format_user(user):
         'name',
         'description',
         'password_expires_at',
+        'options',
     )
     return (
         column_headers,
@@ -58,7 +61,7 @@ def _format_user(user):
 
 
 def _get_options_for_user(identity_client, parsed_args):
-    options = {}
+    options: dict[str, ty.Any] = {}
     if parsed_args.ignore_lockout_failure_attempts:
         options['ignore_lockout_failure_attempts'] = True
     if parsed_args.no_ignore_lockout_failure_attempts:
@@ -288,7 +291,7 @@ class CreateUser(command.ShowOne):
         elif parsed_args.password_prompt:
             password = utils.get_password(self.app.stdin)
 
-        if not parsed_args.password:
+        if not password:
             LOG.warning(
                 _(
                     "No password was supplied, authentication will fail "
@@ -377,7 +380,7 @@ class DeleteUser(command.Command):
 
         if errors > 0:
             total = len(parsed_args.users)
-            msg = _("%(errors)s of %(total)s users failed " "to delete.") % {
+            msg = _("%(errors)s of %(total)s users failed to delete.") % {
                 'errors': errors,
                 'total': total,
             }
@@ -411,6 +414,24 @@ class ListUser(command.Lister):
             default=False,
             help=_('List additional fields in output'),
         )
+        parser.add_argument(
+            '--enabled',
+            action='store_true',
+            dest='is_enabled',
+            default=None,
+            help=_(
+                'List only enabled users, does nothing with --project and --group'
+            ),
+        )
+        parser.add_argument(
+            '--disabled',
+            action='store_false',
+            dest='is_enabled',
+            default=None,
+            help=_(
+                'List only disabled users, does nothing with --project and --group'
+            ),
+        )
         return parser
 
     def take_action(self, parsed_args):
@@ -430,6 +451,9 @@ class ListUser(command.Lister):
                 ignore_missing=False,
             ).id
 
+        if parsed_args.is_enabled is not None:
+            enabled = parsed_args.is_enabled
+
         if parsed_args.project:
             if domain is not None:
                 project = identity_client.find_project(
@@ -468,9 +492,15 @@ class ListUser(command.Lister):
                 group=group,
             )
         else:
-            data = identity_client.users(
-                domain_id=domain,
-            )
+            if parsed_args.is_enabled is not None:
+                data = identity_client.users(
+                    domain_id=domain,
+                    is_enabled=enabled,
+                )
+            else:
+                data = identity_client.users(
+                    domain_id=domain,
+                )
 
         # Column handling
         if parsed_args.long:
@@ -612,10 +642,12 @@ class SetUser(command.Command):
         if parsed_args.description:
             kwargs['description'] = parsed_args.description
         if parsed_args.project:
-            project_domain_id = identity_client.find_domain(
-                name_or_id=parsed_args.project_domain,
-                ignore_missing=False,
-            ).id
+            project_domain_id = None
+            if parsed_args.project_domain:
+                project_domain_id = identity_client.find_domain(
+                    name_or_id=parsed_args.project_domain,
+                    ignore_missing=False,
+                ).id
             project_id = identity_client.find_project(
                 name_or_id=parsed_args.project,
                 ignore_missing=False,
@@ -656,6 +688,8 @@ class SetPasswordUser(command.Command):
 
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.sdk_connection.identity
+        conn = self.app.client_manager.sdk_connection
+        user_id = conn.config.get_auth().get_user_id(conn.identity)
 
         # FIXME(gyee): there are two scenarios:
         #
@@ -698,7 +732,9 @@ class SetPasswordUser(command.Command):
             )
 
         identity_client.update_user(
-            current_password=current_password, password=password
+            user=user_id,
+            current_password=current_password,
+            password=password,
         )
 
 
diff -pruN 7.4.0-3/openstackclient/image/client.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/client.py
--- 7.4.0-3/openstackclient/image/client.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/client.py	2025-07-07 22:41:56.000000000 +0000
@@ -11,7 +11,6 @@
 #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #   License for the specific language governing permissions and limitations
 #   under the License.
-#
 
 import logging
 
@@ -21,13 +20,11 @@ from openstackclient.i18n import _
 
 LOG = logging.getLogger(__name__)
 
+# global variables used when building the shell
 DEFAULT_API_VERSION = '2'
 API_VERSION_OPTION = 'os_image_api_version'
 API_NAME = 'image'
-API_VERSIONS = {
-    '1': 'openstack.connection.Connection',
-    '2': 'openstack.connection.Connection',
-}
+API_VERSIONS = ('1', '2')
 
 
 def make_client(instance):
@@ -49,3 +46,8 @@ def build_option_parser(parser):
         % DEFAULT_API_VERSION,
     )
     return parser
+
+
+def check_api_version(check_version):
+    # SDK supports auto-negotiation for us: always return True
+    return True
diff -pruN 7.4.0-3/openstackclient/image/v1/image.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v1/image.py
--- 7.4.0-3/openstackclient/image/v1/image.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v1/image.py	2025-07-07 22:41:56.000000000 +0000
@@ -30,12 +30,6 @@ from osc_lib import utils
 
 from openstackclient.i18n import _
 
-if os.name == "nt":
-    import msvcrt
-else:
-    msvcrt = None
-
-
 CONTAINER_CHOICES = ["ami", "ari", "aki", "bare", "docker", "ova", "ovf"]
 DEFAULT_CONTAINER_FORMAT = 'bare'
 DEFAULT_DISK_FORMAT = 'raw'
@@ -53,7 +47,6 @@ DISK_CHOICES = [
     "ploop",
 ]
 
-
 LOG = logging.getLogger(__name__)
 
 
@@ -323,8 +316,10 @@ class CreateImage(command.ShowOne):
             else:
                 # Read file from stdin
                 if not sys.stdin.isatty():
-                    if msvcrt:
-                        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+                    if os.name == "nt":
+                        import msvcrt
+
+                        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)  # type: ignore
                     if hasattr(sys.stdin, 'buffer'):
                         kwargs['data'] = sys.stdin.buffer
                     else:
@@ -384,8 +379,7 @@ class DeleteImage(command.Command):
             except Exception as e:
                 result += 1
                 msg = _(
-                    "Failed to delete image with name or "
-                    "ID '%(image)s': %(e)s"
+                    "Failed to delete image with name or ID '%(image)s': %(e)s"
                 )
                 LOG.error(msg, {'image': image, 'e': e})
 
@@ -468,7 +462,7 @@ class ListImage(command.Lister):
             kwargs['is_private'] = True
 
         if parsed_args.long:
-            columns = (
+            columns: tuple[str, ...] = (
                 'ID',
                 'Name',
                 'Disk Format',
@@ -481,7 +475,7 @@ class ListImage(command.Lister):
                 'owner_id',
                 'properties',
             )
-            column_headers = (
+            column_headers: tuple[str, ...] = (
                 'ID',
                 'Name',
                 'Disk Format',
@@ -775,8 +769,10 @@ class SetImage(command.Command):
                     # Read file from stdin
                     if sys.stdin.isatty() is not True:
                         if parsed_args.stdin:
-                            if msvcrt:
-                                msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+                            if os.name == "nt":
+                                import msvcrt
+
+                                msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)  # type: ignore
                             if hasattr(sys.stdin, 'buffer'):
                                 kwargs['data'] = sys.stdin.buffer
                             else:
diff -pruN 7.4.0-3/openstackclient/image/v2/cache.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/cache.py
--- 7.4.0-3/openstackclient/image/v2/cache.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/cache.py	2025-07-07 22:41:56.000000000 +0000
@@ -37,14 +37,18 @@ def _format_image_cache(cached_images):
                 image_obj = copy.deepcopy(image)
                 image_obj['state'] = 'cached'
                 image_obj['last_accessed'] = (
-                    datetime.datetime.utcfromtimestamp(
-                        image['last_accessed']
-                    ).isoformat()
+                    datetime.datetime.fromtimestamp(
+                        image['last_accessed'], tz=datetime.timezone.utc
+                    )
+                    .replace(tzinfo=None)
+                    .isoformat()
                 )
                 image_obj['last_modified'] = (
-                    datetime.datetime.utcfromtimestamp(
-                        image['last_modified']
-                    ).isoformat()
+                    datetime.datetime.fromtimestamp(
+                        image['last_modified'], tz=datetime.timezone.utc
+                    )
+                    .replace(tzinfo=None)
+                    .isoformat()
                 )
                 image_list.append(image_obj)
         elif item == "queued_images":
@@ -131,8 +135,7 @@ class QueueCachedImage(command.Command):
             except Exception as e:
                 failures += 1
                 msg = _(
-                    "Failed to queue image with name or "
-                    "ID '%(image)s': %(e)s"
+                    "Failed to queue image with name or ID '%(image)s': %(e)s"
                 )
                 LOG.error(msg, {'image': image, 'e': e})
 
@@ -171,8 +174,7 @@ class DeleteCachedImage(command.Command)
             except Exception as e:
                 failures += 1
                 msg = _(
-                    "Failed to delete image with name or "
-                    "ID '%(image)s': %(e)s"
+                    "Failed to delete image with name or ID '%(image)s': %(e)s"
                 )
                 LOG.error(msg, {'image': image, 'e': e})
 
diff -pruN 7.4.0-3/openstackclient/image/v2/image.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/image.py
--- 7.4.0-3/openstackclient/image/v2/image.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/image.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,13 +17,16 @@
 
 import argparse
 from base64 import b64encode
+import copy
 import logging
 import os
 import sys
+import typing as ty
+import urllib.parse
 
-from cinderclient import api_versions
 from openstack import exceptions as sdk_exceptions
 from openstack.image import image_signer
+from openstack import utils as sdk_utils
 from osc_lib.api import utils as api_utils
 from osc_lib.cli import format_columns
 from osc_lib.cli import parseractions
@@ -36,12 +39,6 @@ from openstackclient.common import progr
 from openstackclient.i18n import _
 from openstackclient.identity import common as identity_common
 
-if os.name == "nt":
-    import msvcrt
-else:
-    msvcrt = None
-
-
 CONTAINER_CHOICES = ["ami", "ari", "aki", "bare", "docker", "ova", "ovf"]
 DEFAULT_CONTAINER_FORMAT = 'bare'
 DEFAULT_DISK_FORMAT = 'raw'
@@ -60,7 +57,6 @@ DISK_CHOICES = [
 ]
 MEMBER_STATUS_CHOICES = ["accepted", "pending", "rejected", "all"]
 
-
 LOG = logging.getLogger(__name__)
 
 
@@ -154,8 +150,10 @@ def get_data_from_stdin():
         image = sys.stdin
         if hasattr(sys.stdin, 'buffer'):
             image = sys.stdin.buffer
-        if msvcrt:
-            msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+        if os.name == "nt":
+            import msvcrt
+
+            msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)  # type: ignore
 
         return image
     else:
@@ -359,8 +357,7 @@ class CreateImage(command.ShowOne):
             action="store_true",
             default=False,
             help=_(
-                "Show upload progress bar "
-                "(ignored if passing data via stdin)"
+                "Show upload progress bar (ignored if passing data via stdin)"
             ),
         )
         parser.add_argument(
@@ -401,8 +398,7 @@ class CreateImage(command.ShowOne):
             metavar="<tag>",
             action='append',
             help=_(
-                "Set a tag on this image "
-                "(repeat option to set multiple tags)"
+                "Set a tag on this image (repeat option to set multiple tags)"
             ),
         )
         parser.add_argument(
@@ -434,7 +430,7 @@ class CreateImage(command.ShowOne):
 
         # Build an attribute dict from the parsed args, only include
         # attributes that were actually set on the command line
-        kwargs = {'allow_duplicates': True}
+        kwargs: dict[str, ty.Any] = {'allow_duplicates': True}
         copy_attrs = (
             'name',
             'id',
@@ -582,7 +578,7 @@ class CreateImage(command.ShowOne):
         return _format_image(image)
 
     def _take_action_volume(self, parsed_args):
-        volume_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
 
         unsupported_opts = {
             # 'name',  # 'name' is a positional argument and will always exist
@@ -613,12 +609,14 @@ class CreateImage(command.ShowOne):
                 # version
                 LOG.warning(msg % opt_name)
 
-        source_volume = utils.find_resource(
-            volume_client.volumes,
-            parsed_args.volume,
+        source_volume = volume_client.find_volume(
+            parsed_args.volume, ignore_missing=False
         )
-        kwargs = {}
-        if volume_client.api_version < api_versions.APIVersion('3.1'):
+        kwargs: dict[str, ty.Any] = {
+            'visibility': None,
+            'protected': None,
+        }
+        if not sdk_utils.supports_microversion(volume_client, '3.1'):
             if parsed_args.visibility or parsed_args.is_protected is not None:
                 msg = _(
                     '--os-volume-api-version 3.1 or greater is required '
@@ -627,20 +625,18 @@ class CreateImage(command.ShowOne):
                 )
                 raise exceptions.CommandError(msg)
         else:
-            kwargs.update(
-                visibility=parsed_args.visibility or 'private',
-                protected=parsed_args.is_protected or False,
-            )
+            kwargs['visibility'] = parsed_args.visibility or 'private'
+            kwargs['protected'] = parsed_args.is_protected or False
 
-        response, body = volume_client.volumes.upload_to_image(
+        response = volume_client.upload_volume_to_image(
             source_volume.id,
-            parsed_args.force,
             parsed_args.name,
-            parsed_args.container_format,
-            parsed_args.disk_format,
+            force=parsed_args.force,
+            disk_format=parsed_args.disk_format,
+            container_format=parsed_args.container_format,
             **kwargs,
         )
-        info = body['os-volume_upload_image']
+        info = copy.deepcopy(response)
         try:
             info['volume_type'] = info['volume_type']['name']
         except TypeError:
@@ -705,8 +701,7 @@ class DeleteImage(command.Command):
             except Exception as e:
                 result += 1
                 msg = _(
-                    "Failed to delete image with name or "
-                    "ID '%(image)s': %(e)s"
+                    "Failed to delete image with name or ID '%(image)s': %(e)s"
                 )
                 LOG.error(msg, {'image': image, 'e': e})
 
@@ -884,7 +879,7 @@ class ListImage(command.Lister):
         if parsed_args.is_hidden:
             kwargs['is_hidden'] = parsed_args.is_hidden
         if parsed_args.long:
-            columns = (
+            columns: tuple[str, ...] = (
                 'ID',
                 'Name',
                 'Disk Format',
@@ -897,7 +892,7 @@ class ListImage(command.Lister):
                 'owner_id',
                 'tags',
             )
-            column_headers = (
+            column_headers: tuple[str, ...] = (
                 'ID',
                 'Name',
                 'Disk Format',
@@ -959,7 +954,7 @@ class ListImageProjects(command.Lister):
 
     def take_action(self, parsed_args):
         image_client = self.app.client_manager.image
-        columns = ("Image ID", "Member ID", "Status")
+        columns: tuple[str, ...] = ("Image ID", "Member ID", "Status")
 
         image_id = image_client.find_image(
             parsed_args.image,
@@ -1153,8 +1148,7 @@ class SetImage(command.Command):
             default=None,
             action='append',
             help=_(
-                "Set a tag on this image "
-                "(repeat option to set multiple tags)"
+                "Set a tag on this image (repeat option to set multiple tags)"
             ),
         )
         parser.add_argument(
@@ -1457,7 +1451,6 @@ class UnsetImage(command.Command):
             ignore_missing=False,
         )
 
-        kwargs = {}
         tagret = 0
         propret = 0
         if parsed_args.tags:
@@ -1466,10 +1459,11 @@ class UnsetImage(command.Command):
                     image_client.remove_tag(image.id, k)
                 except Exception:
                     LOG.error(
-                        _("tag unset failed, '%s' is a " "nonexistent tag "), k
+                        _("tag unset failed, '%s' is a nonexistent tag "), k
                     )
                     tagret += 1
 
+        kwargs: dict[str, ty.Any] = {}
         if parsed_args.properties:
             for k in parsed_args.properties:
                 if k in image:
@@ -1519,7 +1513,7 @@ class UnsetImage(command.Command):
             raise exceptions.CommandError(msg)
         elif propret > 0:
             msg = _(
-                "Failed to unset %(propret)s of %(proptotal)s" " properties."
+                "Failed to unset %(propret)s of %(proptotal)s properties."
             ) % {'propret': propret, 'proptotal': proptotal}
             raise exceptions.CommandError(msg)
 
@@ -1551,8 +1545,7 @@ class StageImage(command.Command):
             action='store_true',
             default=False,
             help=_(
-                'Show upload progress bar '
-                '(ignored if passing data via stdin)'
+                'Show upload progress bar (ignored if passing data via stdin)'
             ),
         )
         parser.add_argument(
@@ -1583,7 +1576,7 @@ class StageImage(command.Command):
         else:
             fp = get_data_from_stdin()
 
-        kwargs = {}
+        kwargs: dict[str, ty.Any] = {}
 
         if parsed_args.progress and parsed_args.filename:
             # NOTE(stephenfin): we only show a progress bar if the user
@@ -1689,7 +1682,8 @@ class ImportImage(command.ShowOne):
                 "'copy-image' import method)"
             ),
         )
-        parser.add_argument(
+        allow_failure_group = parser.add_mutually_exclusive_group()
+        allow_failure_group.add_argument(
             '--allow-failure',
             action='store_true',
             dest='allow_failure',
@@ -1700,9 +1694,9 @@ class ImportImage(command.ShowOne):
                 'Only usable with --stores or --all-stores'
             ),
         )
-        parser.add_argument(
+        allow_failure_group.add_argument(
             '--disallow-failure',
-            action='store_true',
+            action='store_false',
             dest='allow_failure',
             default=True,
             help=_(
@@ -1751,6 +1745,12 @@ class ImportImage(command.ShowOne):
                     "'--method=web-download'"
                 )
                 raise exceptions.CommandError(msg)
+            _parsed = urllib.parse.urlparse(parsed_args.uri)
+            if not all({_parsed.scheme, _parsed.netloc}):
+                msg = _("'%(uri)s' is not a valid url")
+                raise exceptions.CommandError(
+                    msg % {'uri': parsed_args.uri},
+                )
         else:
             if parsed_args.uri:
                 msg = _(
@@ -1866,8 +1866,8 @@ class StoresInfo(command.Lister):
     def take_action(self, parsed_args):
         image_client = self.app.client_manager.image
         try:
-            columns = ("id", "description", "is_default")
-            column_headers = ("ID", "Description", "Default")
+            columns: tuple[str, ...] = ("id", "description", "is_default")
+            column_headers: tuple[str, ...] = ("ID", "Description", "Default")
             if parsed_args.detail:
                 columns += ("properties",)
                 column_headers += ("Properties",)
diff -pruN 7.4.0-3/openstackclient/image/v2/metadef_namespaces.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/metadef_namespaces.py
--- 7.4.0-3/openstackclient/image/v2/metadef_namespaces.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/metadef_namespaces.py	2025-07-07 22:41:56.000000000 +0000
@@ -169,9 +169,10 @@ class DeleteMetadefNamespace(command.Com
 
         if result > 0:
             total = len(parsed_args.namespace)
-            msg = _(
-                "%(result)s of %(total)s namespace failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s namespace failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
diff -pruN 7.4.0-3/openstackclient/image/v2/metadef_resource_type_association.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/metadef_resource_type_association.py
--- 7.4.0-3/openstackclient/image/v2/metadef_resource_type_association.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/metadef_resource_type_association.py	2025-07-07 22:41:56.000000000 +0000
@@ -22,10 +22,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
diff -pruN 7.4.0-3/openstackclient/image/v2/metadef_resource_types.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/metadef_resource_types.py
--- 7.4.0-3/openstackclient/image/v2/metadef_resource_types.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/image/v2/metadef_resource_types.py	2025-07-07 22:41:56.000000000 +0000
@@ -23,8 +23,7 @@ class ListMetadefResourceTypes(command.L
 
     def take_action(self, parsed_args):
         image_client = self.app.client_manager.image
-        kwargs = {}
-        data = image_client.metadef_resource_types(**kwargs)
+        data = image_client.metadef_resource_types()
         columns = ['Name']
         column_headers = columns
         return (
diff -pruN 7.4.0-3/openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po
--- 7.4.0-3/openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po	2025-07-07 22:41:56.000000000 +0000
@@ -1,15 +1,14 @@
-# Andreas Jaeger <jaegerandi@gmail.com>, 2017. #zanata
 # işbaran akçayır <isbaran@gmail.com>, 2017. #zanata
 msgid ""
 msgstr ""
 "Project-Id-Version: python-openstackclient VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2018-02-25 01:10+0000\n"
+"POT-Creation-Date: 2025-04-01 18:07+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2017-08-15 12:09+0000\n"
-"Last-Translator: Andreas Jaeger <jaegerandi@gmail.com>\n"
+"PO-Revision-Date: 2017-08-14 07:58+0000\n"
+"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
 "Language-Team: Turkish (Turkey)\n"
 "Language: tr_TR\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -17,17 +16,6 @@ msgstr ""
 "X-POOTLE-MTIME: 1502656444.000000\n"
 
 #, python-format
-msgid ""
-"\"Create\" rule command for type \"%(rule_type)s\" requires arguments "
-"%(args)s"
-msgstr ""
-"\"%(rule_type)s\" türü için \"create\" kural komutu %(args)s argümanlarını "
-"gerektirir"
-
-msgid "\"Create\" rule command requires argument \"type\""
-msgstr "\"Create\" kural komutu için \"type\" argümanı zorunludur"
-
-#, python-format
 msgid "%(errors)s of %(total)s groups failed to delete."
 msgstr "%(total)s gruptan %(errors)s grup silinirken hata oluştu."
 
@@ -52,10 +40,6 @@ msgid "%(num)s of %(total)s %(resource)s
 msgstr "%(total)s %(resource)s'tan %(num)s tanesi silinirken hata oluştu."
 
 #, python-format
-msgid "%(result)s of %(total)s %(resource)ss failed to delete."
-msgstr "%(total)s'ın %(result)s %(resource)s'ların silinmesi başarısız."
-
-#, python-format
 msgid "%(result)s of %(total)s EC2 keys failed to delete."
 msgstr ""
 "%(total)s EC2 anahtarlarından %(result)s anahtarın silme işlemi başarısız."
@@ -166,10 +150,6 @@ msgid "%(result)s of %(total)s network s
 msgstr "%(total)s ağ dilimlerinin %(result)s tanesi silinirken hata oluştu."
 
 #, python-format
-msgid "%(result)s of %(total)s policys failed to delete."
-msgstr "%(total)s politikadan %(result)s tanesi silinirken hata oluştu."
-
-#, python-format
 msgid "%(result)s of %(total)s ports failed to delete."
 msgstr ""
 "%(total)s bağlantı noktasından %(result)s tanesi silinirken hata oluştu."
@@ -279,24 +259,12 @@ msgstr ""
 "Varolan uzak disk bölümünden yeni görüntüsünden yeni disk bölümü anlık "
 "görüntüsü oluştururken 'force' seçeneği çalışmaz"
 
-msgid "'--retype-policy' option will not work without '--type' option"
-msgstr "'--retype-policy' seçeneği '--type' seçeneği olmadan çalışmaz"
-
 msgid "--project is only allowed with --private"
 msgstr "--project sadece --private ile kullanılabilir"
 
-msgid ""
-"--size is a required option if snapshot or source volume is not specified."
-msgstr ""
-"Anlık görüntü veya kaynak disk bölümü belirtilmezse --size gerekli bir "
-"seçenektir."
-
 msgid "A service URL where SAML assertions are being sent (required)"
 msgstr "SAML bildirimlerinin gönderildiği bir hizmet URL'i (gerekli)"
 
-msgid "Accept the image membership"
-msgstr "İmaj üyeliğini kabul et"
-
 msgid "Accept volume transfer request."
 msgstr "Disk bölümü aktarım isteğini kabul et."
 
@@ -358,27 +326,12 @@ msgstr "L3 aracısına yönlendirici ekl
 msgid "Add router to an agent"
 msgstr "Bir ajana yönlendirici ekle"
 
-msgid "Add security group to server"
-msgstr "Sunucuya güvenlik grubu ekle"
-
 msgid "Add user to group"
 msgstr "Gruba kullanıcı ekle"
 
-msgid "Add volume to server"
-msgstr "Disk bölümünü sunucuya ekle"
-
 msgid "Add volume(s) to consistency group"
 msgstr "Uyum grubuna disk bölümleri ekle"
 
-msgid ""
-"Additional route for this subnet e.g.: destination=10.10.0.0/16,"
-"gateway=192.168.71.254 destination: destination subnet (in CIDR notation) "
-"gateway: nexthop IP address (repeat option to add multiple routes)"
-msgstr ""
-"Bu alt ağ için ek yönlendirici örn: hedef=10.10.0.0/16,geçit=192.168.71.254 "
-"hedef: hedef alt ağ (CIDR gösteriminde) geçit: bir sonraki durak IP adresi "
-"(birden fazla yölendirici eklemek için tekrarlanacak seçenek)"
-
 msgid "Address scope to display (name or ID)"
 msgstr "Gösterilecek adres kapsamı (isim veya ID)"
 
@@ -388,9 +341,6 @@ msgstr "Değiştirilecek adres kapsamı
 msgid "Address scope(s) to delete (name or ID)"
 msgstr "Silinecek adres kapsam(lar)ı (isim veya ID)"
 
-msgid "Adds a role assignment to a user or group on a domain or project"
-msgstr "Bir alandaki veya projedeki bir kullanıcıya veya gruba rol atama ekler"
-
 msgid "Agent from which router will be removed (ID only)"
 msgstr "Yönlendiricinin kaldırılacağı ajan (yalnızca ID)"
 
@@ -419,41 +369,15 @@ msgid "Allocate port on host <host-id> (
 msgstr "<host-id> ana bilgisayarında bağlantı noktası ayır (sadece ID)"
 
 msgid ""
-"Allocation pool IP addresses for this subnet e.g.: start=192.168.199.2,"
-"end=192.168.199.254 (repeat option to add multiple IP addresses)"
-msgstr ""
-"Bu alt ağ için ayırma havuzu IP adresleri örn: başlangıç=192.168.199.2,"
-"bitiş=192.168.199.254 (birden fazla IP adresi eklemek için seçeneği tekrarla)"
-
-msgid ""
-"Allocation pool IP addresses to be removed from this subnet e.g.: "
-"start=192.168.199.2,end=192.168.199.254 (repeat option to unset multiple "
-"allocation pools)"
-msgstr ""
-"Bu altağdan silinecek IP adres tahsis havuzu örn: başlangıç=192.168.199.2,"
-"bitiş=192.168.199.254 (birden fazla tahsis havuzu ayarını kaldırmak için "
-"seçeneği tekrarla)"
-
-msgid ""
 "Allow <project> to access private flavor (name or ID) (Must be used with --"
 "private option)"
 msgstr ""
 "<project>'nin özel flavor'a erişmesine izin verin (isim veya ID) (--private "
 "seçeneği ile beraber kullanılmalı)"
 
-msgid ""
-"Allow <project> to access private type (name or ID) (Must be used with --"
-"private option)"
-msgstr ""
-"Özel türe erişimek için <project>'ye izin ver (isim veya ID) (--private "
-"seçeneği ile kullanılması zorunludur)"
-
 msgid "Allow delete in state other than error or available"
 msgstr "Hata veya kullanılabilirden başka durumda silinmesine izin ver"
 
-msgid "Allow disk over-commit on the destination host"
-msgstr "Hedef ana bilgisayarda disk aşırı-işlemeye izin ver"
-
 msgid "Allow image to be deleted (default)"
 msgstr "İmajın silinmesine izin ver (varsayılan)"
 
@@ -463,16 +387,10 @@ msgstr "Kullanımdaki birimi yedeklemeye
 msgid "Allow to delete in-use QoS specification(s)"
 msgstr "Kullanımdaki QoS özelliklerini silmeye izin ver"
 
-msgid "Allow volume to be attached more than once (default to False)"
-msgstr "Diskin birden fazla eklenmesine izin ver (varsayılan olarak False)"
-
 #, python-format
 msgid "An error occurred when reading rules from file %(path)s: %(error)s"
 msgstr "%(path)s dosaysından kurallar okunurken hata oluştu: %(error)s"
 
-msgid "Anchor for paging"
-msgstr "Sayfalama için sabitleyici"
-
 msgid "Apply rule to incoming network traffic (default)"
 msgstr "Kuralı gelen trafiğe uygula (varsayılan)"
 
@@ -480,13 +398,6 @@ msgid "Apply rule to outgoing network tr
 msgstr "Giden ağ trafiğine kural uygula"
 
 msgid ""
-"Arbitrary scheduler hint key-value pairs to help boot an instance (repeat "
-"option to set multiple hints)"
-msgstr ""
-"İsteğe bağlı bir önyüklemeye yardımcı olmak için keyfi zamanlayıcı ipucu "
-"anahtar-değer çiftleri (birden fazla ipucu ayarlamak için seçeneği tekrarla)"
-
-msgid ""
 "Argument --dst-port not allowed with arguments --icmp-type and --icmp-code"
 msgstr ""
 "--dst-port argümanı --icmp-type ve --icmp-code argümanları ile kullanılamaz"
@@ -494,9 +405,6 @@ msgstr ""
 msgid "Argument --icmp-type required with argument --icmp-code"
 msgstr "--icmp-type argümanı --icmp-code ile kullanılması zorunlu"
 
-msgid "Assocaite the floating IP with port (name or ID)"
-msgstr "Yüzen IP'yi bağlantı noktasıyla ilişkilendirin (ad veya kimlik)"
-
 msgid "Associate a QoS specification to a volume type"
 msgstr "Bir disk bölümü türüyle QoS özelliklerini ilişkilendir"
 
@@ -532,9 +440,6 @@ msgstr ""
 msgid "Authentication URL of remote federated service provider (required)"
 msgstr "Uzak federe servis sağlayıcının kimlik doğrulama URL'si (gerekli)"
 
-msgid "Authentication token to use"
-msgstr "Kullanılacak yetkilendirme jetonu"
-
 msgid "Authorize a request token"
 msgstr "Bir istek jetonu yetkilendir"
 
@@ -615,16 +520,9 @@ msgstr "Mevcut kullanıcının parolası
 msgid "Check user membership in group"
 msgstr "Kullanıcının grup üyeliğini kontrol et"
 
-msgid "Clean project resources, but don't delete the project"
-msgstr "Projenin kaynaklarını temizle ama projeyi silme"
-
 msgid "Clean resources associated with a project"
 msgstr "Bir proje ile alakalı kaynakları temizle"
 
-#, python-format
-msgid "Clear all tags associated with the %s"
-msgstr "%s ile ilişkili tüm etiketleri sil"
-
 msgid ""
 "Clear associated allocation-pools from the subnet. Specify both --allocation-"
 "pool and --no-allocation-pool to overwrite the current allocation pool "
@@ -643,15 +541,6 @@ msgstr ""
 "seçeneklerinin her ikisini de belirtin."
 
 msgid ""
-"Clear existing allowed-address pairs associatedwith this port.(Specify both "
-"--allowed-address and --no-allowed-addressto overwrite the current allowed-"
-"address pairs)"
-msgstr ""
-"Bu bağlantı noktasıyla ilişkili mevcut izinli adres çiftlerini temizleyin."
-"(Mevcut  izinli adres çiftinin üzerinde yazmak için --allowed-address ve --"
-"no-allowed-addressto seçeneklerinin her ikisini de belirtiniz)"
-
-msgid ""
 "Clear existing information of DNS Nameservers. Specify both --dns-nameserver "
 "and --no-dns-nameserver to overwrite the current DNS Nameserver information."
 msgstr ""
@@ -659,26 +548,6 @@ msgstr ""
 "bilgisinin üzerine yazmak için --dns-nameserver ve --no-dns-nameserver "
 "özelliklerini belirle."
 
-msgid ""
-"Clear existing information of binding:profile.Specify both --binding-profile "
-"and --no-binding-profile to overwrite the current binding:profile "
-"information."
-msgstr ""
-"binding:profile'in mevcut bilgilerini temizle. Mevcut binding:profile "
-"bilgisinin üzerine yazmak için --binding-profile ve --no-binding-profile her "
-"ikisini de belirtin."
-
-msgid "Clear existing information of data plane status"
-msgstr "Mevcut veri düzlemi durumu bilgilerini temizle"
-
-msgid ""
-"Clear existing information of fixed IP addresses.Specify both --fixed-ip and "
-"--no-fixed-ip to overwrite the current fixed IP addresses."
-msgstr ""
-"Sabit IP adresleri için mevcut bilgileri silin. Geçerli sabit IP "
-"adreslerinin üzerine yazmak için hem --fixed-ip hem de --no-fixed-ip "
-"belirtin."
-
 msgid "Clear existing security groups associated with this port"
 msgstr "Bu bağlantı noktasıyla ilişkili mevcut güvenlik gruplarını temizle"
 
@@ -687,21 +556,6 @@ msgstr ""
 "Yönlendiricinin yüksek kullanılabilirlik özelliğini temizle (sadece devre "
 "dışı bırakılmış yönlendirici)"
 
-msgid ""
-"Clear routes associated with the router. Specify both --route and --no-route "
-"to overwrite current value of route."
-msgstr ""
-"Yönlendirici ile ilişkili yönleri temizle. Mevcut yön değerinin üzerine "
-"yazmak için hem --route hem de --no-route seçeneklerini belirtin."
-
-#, python-format
-msgid ""
-"Clear tags associated with the %s. Specify both --tag and --no-tag to "
-"overwrite current tags"
-msgstr ""
-"%s ile ilgili etiketleri temizle. Mevcut etiketlerin üzerine yazmak için hem "
-"--tag hem de --no-tag seçeneğini belirtin"
-
 msgid "Command Failed: One or more of the operations failed"
 msgstr "Komut başarısız: Bir veya birden fazla işlem başarısız"
 
@@ -716,12 +570,6 @@ msgstr "Hesaplama API sürümü, varsay
 msgid "Compute service %(service)s of host %(host)s failed to set."
 msgstr "Ana bilgisayar %(host)s'ın hesap hizmeti %(service)s ayarlanamadı."
 
-msgid "Compute service(s) to delete (ID only)"
-msgstr "Hesaplama servis(ler)ini sil"
-
-msgid "Confirm server resize is complete"
-msgstr "Sunucu yeniden boyutlandırmasının tamamlandığını doğrula"
-
 msgid "Consistency group containing <volume> (name or ID)"
 msgstr "<volume>'ü içeren tutarlılık grubu (isim veya ID)"
 
@@ -775,10 +623,6 @@ msgstr "Silinecek alıcı(lar)"
 msgid "Container for new object"
 msgstr "Yeni nesne için kap"
 
-#, python-format
-msgid "Container name is %s characters long, the default limit is 256"
-msgstr "Kap ismi %s karakter uzunluğunda, varsayılan sınır 256'dır"
-
 msgid "Container to display"
 msgstr "Gösterilecek kap"
 
@@ -817,63 +661,9 @@ msgstr ""
 "net-id=<network>' parametresi için bir sarmalayıcıdır. Daha gelişmiş "
 "kullanım durumları için, '--nic' parametresine bakın."
 
-msgid ""
-"Create a NIC on the server and connect it to port. Specify option multiple "
-"times to create multiple NICs. This is a wrapper for the '--nic port-"
-"id=<pord>' parameter that provides simple syntax for the standard use case "
-"of connecting a new server to a given port. For more advanced use cases, "
-"refer to the '--nic' parameter."
-msgstr ""
-"Sunucuda bir NIC oluşturun ve bağlantı noktasına bağlayın. Birden çok NIC "
-"oluşturmak için seçeneği birden çok kez belirtin. Bu, belirli bir bağlantı "
-"noktasına yeni bir sunucu bağlamak için standart kullanım örneği için basit "
-"sözdizimi sağlayan '--nic port-id=<pord>' parametresi için bir "
-"sarmalayıcıdır. Daha gelişmiş kullanım durumları için, '--nic' parametresine "
-"bakın."
-
-msgid ""
-"Create a NIC on the server. Specify option multiple times to create multiple "
-"NICs. Either net-id or port-id must be provided, but not both. net-id: "
-"attach NIC to network with this UUID, port-id: attach NIC to port with this "
-"UUID, v4-fixed-ip: IPv4 fixed address for NIC (optional), v6-fixed-ip: IPv6 "
-"fixed address for NIC (optional), none: (v2.37+) no network is attached, "
-"auto: (v2.37+) the compute service will automatically allocate a network. "
-"Specifying a --nic of auto or none cannot be used with any other --nic value."
-msgstr ""
-"Sunucuda bir NIC oluştur. Birden fazla NIC oluşturmak için seçeneği birden "
-"fazla kere belirtin. Ya net-id ya da port-id sağlanmalı, ikisi bir arada "
-"değil. net-id: NIC'nin ağa ekleneceği UUID, port-id: NIC'nin bağlantı "
-"noktasına takılacağı UUID, v4-fixed-ip: NIC için sabit IPv4 adresi "
-"(seçimli), v6-fixed-ip: NIC için sabit IPv6 adresi (seçimli), none: (v2.37+) "
-"hiç ağ takılmaz, auto: (v2.37+) hesaplama servisi otomatik olarak bir ağ "
-"ayırır. Auto veya none'ı bir --nic ile belirtmek başka bir --nic değeri ile "
-"kullanılamaz."
-
 msgid "Create a QoS policy"
 msgstr "QoS politikası oluştur"
 
-msgid ""
-"Create a block device on the server.\n"
-"Block device mapping in the format\n"
-"<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>\n"
-"<dev-name>: block device name, like: vdb, xvdc (required)\n"
-"<id>: UUID of the volume or snapshot (required)\n"
-"<type>: volume or snapshot; default: volume (optional)\n"
-"<size(GB)>: volume size if create from snapshot (optional)\n"
-"<delete-on-terminate>: true or false; default: false (optional)\n"
-"(optional extension)"
-msgstr ""
-"Sunucu üzerinde blok aygıtı oluştur.\n"
-"Blok aygıtı eşleşme formatı\n"
-"<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>\n"
-"<dev-name>: blok aygıt ismi, örn: vdb, xvdc (gerekli)\n"
-"<id>: disk bölümünün veya anlık görüntünün UUID'si (gerekli)\n"
-"<type>: disk bölümü veya anlık görüntü; varsayılan: disk bölümü (seçimli)\n"
-"<size(GB)>: eğer anlık görüntüden oluşturulduysa disk bölümü boyutu "
-"(seçimli)\n"
-"<delete-on-terminate>: true veya false; varsayılan: false (seçimli)\n"
-"(seçimli uzantı)"
-
 msgid "Create a centralized router"
 msgstr "Merkezi bir yönlendirici oluştur"
 
@@ -931,9 +721,6 @@ msgstr "Bir altağ oluşturun"
 msgid "Create an access token"
 msgstr "Erişim jetonu oluştur"
 
-msgid "Create compute agent"
-msgstr "Hesaplama ajanı oluştur"
-
 msgid ""
 "Create credentials for user (name or ID; default: current authenticated user)"
 msgstr ""
@@ -947,9 +734,6 @@ msgstr ""
 "Projede kimlik bilgileri oluştur (isim veya ID; varsayılan: mevcut kimlik "
 "doğrulama yapılmış proje)"
 
-msgid "Create description for meter"
-msgstr "Sayaç için açıklama oluştur"
-
 msgid "Create floating IP"
 msgstr "Yüzen IP oluştur"
 
@@ -968,9 +752,6 @@ msgstr "Yeni Ağ QoS kuralı oluştur"
 msgid "Create new QoS specification"
 msgstr "Yeni QoS özelliği oluştur"
 
-msgid "Create new backup"
-msgstr "Yeni yedek oluştur"
-
 msgid "Create new consistency group snapshot."
 msgstr "Yeni tutarlılık grubu anlık görüntüsü oluştur."
 
@@ -1040,9 +821,6 @@ msgstr "Yeni servis oluştur"
 msgid "Create new service provider"
 msgstr "Yeni servis sağlayıcı oluştur"
 
-msgid "Create new snapshot"
-msgstr "Yeni anlık görüntü oluştur"
-
 msgid "Create new trust"
 msgstr "Yeni güven oluştur"
 
@@ -1067,20 +845,6 @@ msgstr "Bu güvenlik grubunda kural olu
 msgid "Create server boot disk from this image (name or ID)"
 msgstr "Bu imajdan sunucu ön yükleme diski oluştur (isim veya ID)"
 
-msgid ""
-"Create server using this volume as the boot disk (name or ID).\n"
-"This option automatically creates a block device mapping with a boot index "
-"of 0. On many hypervisors (libvirt/kvm for example) this will be device vda. "
-"Do not create a duplicate mapping using --block-device-mapping for this "
-"volume."
-msgstr ""
-"Bu disk bölümünü ön yüklenebilir disk olarak kullanarak sunucu oluştur (isim "
-"veya ID).\n"
-"Bu seçenek otomatik olarak 0 ön yükleme diziniyle bir blok aygıt eşleşmesi "
-"oluşturur. Bir çok yönetici arakatman (örneğin libvirt/kvm) üzerinde bu "
-"aygıt vda'dir. Bu disk bölümü için --block-device-mapping kullanarak birden "
-"fazla eşleşme oluşturmayın."
-
 msgid "Create server with this flavor (name or ID)"
 msgstr "Bu flavor ile sunucu oluştur (isim veya ID)"
 
@@ -1105,14 +869,6 @@ msgstr "Kimlik bilgilerine erişim anaht
 msgid "Credentials access key(s)"
 msgstr "Kimlik bilgilerine erişim anahtar(lar)ı"
 
-msgid ""
-"Custom data to be passed as binding:profile. Data may be passed as "
-"<key>=<value> or JSON. (repeat option to set multiple binding:profile data)"
-msgstr ""
-"binding:profile olarak verilecek özel veri. Veri <key>=<value> şeklinde veya "
-"JSON olarak verilebilir. (birden fazla binding:profile verisi ayarlamak için "
-"seçeneği tekrarlayın)"
-
 msgid "DNS server for this subnet (repeat option to set multiple DNS servers)"
 msgstr ""
 "Bu alt ağ için DNS sunucu (birden fazla DNS sunucusu ayarlamak için seçeneği "
@@ -1156,22 +912,9 @@ msgstr "Qos Politika(lar/s)ını sil"
 msgid "Delete address scope(s)"
 msgstr "Adres kapsam(lar)ını sil"
 
-msgid ""
-"Delete auto allocated topology for a given project. Default is the current "
-"project"
-msgstr ""
-"Belirli bir proje için otomatik ayrılan topolojiyi silin. Varsayılan geçerli "
-"projedir"
-
 msgid "Delete auto allocated topology for project"
 msgstr "Projeye otomatik ayrılan topolojiyi sil"
 
-msgid "Delete backup(s)"
-msgstr "Yedek(ler)i sil"
-
-msgid "Delete compute agent(s)"
-msgstr "Hesaplama ajan(lar)ını sil"
-
 msgid "Delete compute service(s)"
 msgstr "Hesaplama servis(ler)ini sil"
 
@@ -1295,9 +1038,6 @@ msgstr "Servis sağlayıcı(ları/yı) s
 msgid "Delete service(s)"
 msgstr "Servis(ler)i sil"
 
-msgid "Delete snapshot(s)"
-msgstr "Anlık görüntü(yü/leri) sil"
-
 msgid "Delete subnet pool(s)"
 msgstr "Altağ havuzunu sil"
 
@@ -1325,14 +1065,6 @@ msgstr "Disk bölümü türlerini sil"
 msgid "Delete volume(s)"
 msgstr "Disk bölümlerini sil"
 
-#, python-format
-msgid "Deleting %(resource)s : %(id)s"
-msgstr "%(resource)s siliniyor: %(id)s"
-
-#, python-format
-msgid "Deleting project: %s"
-msgstr "Proje siliniyor: %s"
-
 msgid "Description for the flavor"
 msgstr "Flavor için açıklama"
 
@@ -1358,22 +1090,6 @@ msgid "Description of this port"
 msgstr "Bu bağlantı noktasının açıklaması"
 
 msgid ""
-"Desired IP and/or subnet (name or ID)on external gateway: subnet=<subnet>,ip-"
-"address=<ip-address> (repeat option to set multiple fixed IP addresses)"
-msgstr ""
-"Harici geçit üzerinde istenen IP ve/veya altağ: subnet=<subnet>,ip-"
-"address=<ip-address> (birden fazla sabit IP adres ayarlamak için seçeneği "
-"tekrarla)"
-
-msgid ""
-"Desired IP and/or subnet for filtering ports (name or ID): subnet=<subnet>,"
-"ip-address=<ip-address> (repeat option to set multiple fixed IP addresses)"
-msgstr ""
-"Bağlantı noktalarını filtrelemek için tasarlanan IP ve/veya alt ağ (isim "
-"veya ID): subnet=<subnet>,ip-address=<ip-address> (birden fazla sabit IP "
-"adresi ayarlamak için seçeneği tekrarlayın)"
-
-msgid ""
 "Desired IP and/or subnet for this port (name or ID): subnet=<subnet>,ip-"
 "address=<ip-address> (repeat option to set multiple fixed IP addresses)"
 msgstr ""
@@ -1391,22 +1107,6 @@ msgstr ""
 "adresini kaldırmak için seçeneği tekrarlayın)"
 
 msgid ""
-"Desired allowed-address pair which should be removed from this port: ip-"
-"address=<ip-address> [,mac-address=<mac-address>] (repeat option to set "
-"multiple allowed-address pairs)"
-msgstr ""
-"Bu bağlantıdan kaldırılması gereken tasarlanan erişilebilir adres çifti: ip-"
-"address=<ip-address> [,mac-address=<mac-address>] (birden fazla izin verilen "
-"adres çifti ayarlamak için seçeneği tekrarlayın)"
-
-msgid ""
-"Desired key which should be removed from binding:profile(repeat option to "
-"unset multiple binding:profile data)"
-msgstr ""
-"binding:profile'den çıkarılması gereken istenen anahtar (çoklu binding:"
-"profile verisinin ayarını kaldırmak için seçeneği tekrarlayın)"
-
-msgid ""
 "Destination filename (defaults to object name); using '-' as the filename "
 "will print the file to stdout"
 msgstr ""
@@ -1416,9 +1116,6 @@ msgstr ""
 msgid "Destination host (takes the form: host@backend-name#pool)"
 msgstr "Hedef ana bilgisayar (biçemi: anabilgisayar@artalanismi#havuz)"
 
-msgid "Destination port (ssh -p option)"
-msgstr "Hedef bağlantı noktası (ssh -p seçeneği)"
-
 msgid ""
 "Destination port, may be a single port or a starting and ending port range: "
 "137:139. Required for IP protocols TCP and UDP. Ignored for ICMP IP "
@@ -1539,9 +1236,6 @@ msgstr "Adres kapsam detaylarını göst
 msgid "Display aggregate details"
 msgstr "Küme detaylarını göster"
 
-msgid "Display backup details"
-msgstr "Yedek detaylarını göster"
-
 msgid "Display configuration details"
 msgstr "Yapılandırma detaylarını göster"
 
@@ -1584,9 +1278,6 @@ msgstr "Yüzen IP ayrıntılarını gör
 msgid "Display group details"
 msgstr "Grup detaylarını göster"
 
-msgid "Display host details"
-msgstr "Sunucu detaylarını göster"
-
 msgid "Display hypervisor details"
 msgstr "Yönetici ara katman detaylarını göster"
 
@@ -1671,9 +1362,6 @@ msgstr "Servis detaylarını göster"
 msgid "Display service provider details"
 msgstr "Servis sağlayıcı detaylarını göster"
 
-msgid "Display snapshot details"
-msgstr "Anlık görüntü detaylarını göster"
-
 msgid "Display subnet details"
 msgstr "Altağ detaylarını göster"
 
@@ -1701,9 +1389,6 @@ msgstr "Disk bölümü türü detayları
 msgid "Do not make the network VLAN transparent"
 msgstr "Ağ VLAN'ını transparan yapma"
 
-msgid "Do not over-commit disk on the destination host (default)"
-msgstr "Hedef ana bilgisayarda disk aşırı işleme yapma (varsayılan)"
-
 msgid "Do not share meter between projects"
 msgstr "Ölçümleri projeler arasında paylaşma"
 
@@ -1750,10 +1435,6 @@ msgstr ""
 "Grubun ait olduğu alan (isim veya ID). Grup isimlerinde bir çatışma olması "
 "durumunda kullanılabilir."
 
-msgid "Domain the project belongs to (name or ID) [only valid with --absolute]"
-msgstr ""
-"Projenin ait olduğu alan (isim veya ID) [sadece --absolute ile geçerli]"
-
 msgid ""
 "Domain the project belongs to (name or ID). This can be used in case "
 "collisions between project names exist."
@@ -1898,11 +1579,6 @@ msgstr ""
 msgid "Enable port security for this port"
 msgstr "Bu bağlantı noktası için bağlantı noktası güvenliğini etkinleştir"
 
-msgid "Enable port security for this port (Default)"
-msgstr ""
-"Bu bağlantı noktası için bağlantı noktası güvenliğini etkinleştir "
-"(Varsayılan)"
-
 msgid "Enable project"
 msgstr "Projeyi etkinleştir"
 
@@ -1962,9 +1638,6 @@ msgstr "Silinecek uç nokta(lar) (sadece
 msgid "Ephemeral disk size in GB (default 0G)"
 msgstr "GB cinsinden geçici disk boyutu (varsayılan 0G)"
 
-msgid "Error creating server\n"
-msgstr "Sunucu oluşturulurken hata\n"
-
 #, python-format
 msgid "Error creating server backup: %s"
 msgstr "Sunucu yedeği oluşturulurken hata: %s"
@@ -1977,56 +1650,31 @@ msgstr "Sunucu imajı oluşturma hatası
 msgid "Error creating server: %s"
 msgstr "Sunucu oluşturma başarısız: %s"
 
-msgid "Error deleting server\n"
-msgstr "Sunucu silinirken hata\n"
-
 #, python-format
 msgid "Error deleting server: %s"
 msgstr "Sunucu silinirken hata: %s"
 
-msgid "Error migrating server\n"
-msgstr "Sunucu göçü sırasında hata\n"
-
 #, python-format
 msgid "Error migrating server: %s"
 msgstr "Sunucu göçü sırasında hata: %s"
 
-msgid "Error rebooting server\n"
-msgstr "Sunucu yeniden başlatma hatası\n"
-
 #, python-format
 msgid "Error rebooting server: %s"
 msgstr "Sunucu yeniden başlatma hatası: %s"
 
-msgid "Error rebuilding server\n"
-msgstr "Sunucu yeniden yapılandırması sırasında hata\n"
-
 #, python-format
 msgid "Error rebuilding server: %s"
 msgstr "Sunucu yeniden yapılandırması sırasında hata: %s"
 
-msgid "Error resizing server\n"
-msgstr "Sunucunun yeniden boyutlandırması sırasında hata\n"
-
 #, python-format
 msgid "Error resizing server: %s"
 msgstr "Sunucu yeniden boyutlandırma hatası: %s"
 
-msgid "Error retrieving diagnostics data\n"
-msgstr "Teşhis verisi alınırken hata oluştu\n"
-
 #, python-format
 msgid "Error while executing command: %s"
 msgstr "Komut çalıştırılırken hata oluştu: %s"
 
 msgid ""
-"Error: If a user or group is specified, either --domain or --project must "
-"also be specified to list role grants."
-msgstr ""
-"Hata: Bir kullanıcı veya grup belirtilmişse, rol izinlerini listelemek için "
-"--domain veya --project de belirtilmelidir."
-
-msgid ""
 "Ethertype of network traffic (IPv4, IPv6; default: based on IP protocol)"
 msgstr ""
 "Ağ trafiğinin ethertype'ı (IPv4, IPv6; varsayılan: IP protokolüne bağlı)"
@@ -2079,9 +1727,6 @@ msgstr "Hesaplama API'ı uzantıların l
 msgid "Extensions list not supported by Identity API"
 msgstr "Kimlik API için uzantıların listlenmesi desteklenmiyor"
 
-msgid "External Network used as router's gateway (name or ID)"
-msgstr "Yönlendirici geçidi olarak kullanılan Harici Ağ (isim veya ID)"
-
 #, python-format
 msgid "Failed to add project %(project)s access to flavor: %(e)s"
 msgstr "%(project)s projesinin flavor'a erişimi başarısız: %(e)s"
@@ -2099,22 +1744,10 @@ msgid "Failed to clean volume properties
 msgstr "Disk bölümü özelliklerini silme başarısız: %s"
 
 #, python-format
-msgid "Failed to clear flavor property: %s"
-msgstr "Flavor özelliğinin silinmesi başarısız: %s"
-
-#, python-format
 msgid "Failed to create Network QoS rule: %(e)s"
 msgstr "Ağ QoS kuralı oluşturulurken hata oluştu: %(e)s"
 
 #, python-format
-msgid "Failed to delete %(dresult)s of %(total)s images."
-msgstr "%(total)s imajdan %(dresult)s tanesi silinirken hata oluştu."
-
-#, python-format
-msgid "Failed to delete %(resource)s with ID '%(id)s': %(e)s"
-msgstr "'%(id)s' ID'li %(resource)s silinemedi: %(e)s"
-
-#, python-format
 msgid "Failed to delete %(resource)s with name or ID '%(name_or_id)s': %(e)s"
 msgstr ""
 "'%(name_or_id)s' isimli veya ID'li %(resource)s silinirken hata oluştu: %(e)s"
@@ -2355,9 +1988,6 @@ msgstr ""
 "'%(flavor)s' flavor için erişen projelerin listesinin alınma işlemi "
 "başarısız: %(e)s"
 
-msgid "Failed to get an image file."
-msgstr "İmaj dosyası alma başarısız."
-
 #, python-format
 msgid "Failed to remove flavor access from project: %s"
 msgstr "Projeden flavor erişiminin kaldırılması başarısız: %s"
@@ -2390,10 +2020,6 @@ msgid "Failed to set flavor access to pr
 msgstr "Projeye flavor erişiminin ayarlanması başarısız: %s"
 
 #, python-format
-msgid "Failed to set flavor property: %s"
-msgstr "Flavor özelliğinin ayarlanması başarısız: %s"
-
-#, python-format
 msgid "Failed to set image property: %s"
 msgstr "İmaj özelliği ayarlarken hata oluştu: %s"
 
@@ -2430,10 +2056,6 @@ msgid "Failed to set volume type access
 msgstr "Projeye erişim için disk bölümü türü ayarlama başarısız: %s"
 
 #, python-format
-msgid "Failed to set volume type property: %s"
-msgstr "Disk bölümü türü özelliğini ayarlarken hata oluştu: %s"
-
-#, python-format
 msgid "Failed to set volume type: %s"
 msgstr "Disk bölümü türü ayarlanırken hata oluştu: %s"
 
@@ -2470,20 +2092,6 @@ msgid "Failed to unset volume property:
 msgstr "Disk bölümü özelliği ayarlarını kaldırma başarısız: %s"
 
 #, python-format
-msgid "Failed to unset volume type property: %s"
-msgstr "Disk bölümü türü özelliğini kaldırma işlemi başarısız: %s"
-
-#, python-format
-msgid "Failed to update backup name or description: %s"
-msgstr "Yedek ismi ve açıklaması güncellenirken hata oluştu: %s"
-
-#, python-format
-msgid "Failed to update snapshot display name or display description: %s"
-msgstr ""
-"Anlık görüntü görünür ismi veya görünür açıklamasını güncelleme işlemi "
-"başarısız: %s"
-
-#, python-format
 msgid "Failed to update snapshot name or description: %s"
 msgstr "Anlık görüntü adı veya açıklaması güncellenemedi: %s"
 
@@ -2509,22 +2117,11 @@ msgid "Federation protocol(s) to delete
 msgstr "Silinecek federasyon protokol(ü/leri) (isim veya ID)"
 
 msgid ""
-"File to inject into image before boot (repeat option to set multiple files)"
-msgstr ""
-"Önyüklemeden önce imaja enjekte etmek için dosya (birden çok dosyayı "
-"ayarlamak için seçeneği tekrar edin)"
-
-msgid ""
 "Filename for private key to save. If not used, print private key in console."
 msgstr ""
 "Kapalı anahtarın kaydedileceği dosyanın ismi. Kullanılmazsa, kapalı anahtar "
 "konsola basılır."
 
-msgid "Filename for public key to add. If not used, creates a private key."
-msgstr ""
-"Eklenecek açık anahtarın dosya ismi. Kullanılmazsa, bir kapalı anahtar "
-"oluşturur."
-
 msgid "Filename that contains a new set of mapping rules"
 msgstr "Eşleşme kurallarının yeni bir kümesini içeren dosya adı"
 
@@ -2552,10 +2149,6 @@ msgstr "Grup listesini <domain>'e göre
 msgid "Filter group list by <user> (name or ID)"
 msgstr "<user>'ya göre grup listesini filtrele (isim veya ID)"
 
-msgid "Filter hypervisors using <hostname> substring"
-msgstr ""
-"<hostname> alt karakter dizisini kullanarak yönetici arakatmanları filtrele"
-
 msgid "Filter images based on name."
 msgstr "İmajları isme göre filtrele."
 
@@ -2589,12 +2182,6 @@ msgstr "Sonuçları kullanıcıya göre
 msgid "Filter results by volume name"
 msgstr "Sonuçları disk bölümü ismine göre filtrele"
 
-msgid "Filter roles by <project> (name or ID)"
-msgstr "Rolleri <project>'ye göre filtrele (isim veya ID)"
-
-msgid "Filter roles by <user> (name or ID)"
-msgstr "Rolleri <user>'ya göre filtrele (isim veya ID)"
-
 msgid "Filter users by <domain> (name or ID)"
 msgstr "Kullanıcıları <domain>'e göre filtrele (isim veya ID)"
 
@@ -2620,35 +2207,18 @@ msgstr ""
 "Sonuçları bir duruma göre filtrele (\"available\", \"error\", \"creating\", "
 "\"deleting\" veya \"error_deleting\")"
 
-msgid ""
-"Filters results by a status. ('available', 'error', 'creating', 'deleting' "
-"or 'error-deleting')"
-msgstr ""
-"Bir duruma göre sonuçları filtrele. ('kullanılabilir', 'hata', "
-"'oluşturuluyor', 'siliniyor' veya 'silinirken hata')"
-
 msgid "Filters results by a volume (name or ID)."
 msgstr "Bir disk bölümüne göre sonuçları filtrele (isim veya ID)."
 
 msgid "Filters results by the backup name"
 msgstr "Yedek ismine göre sonuçları listele"
 
-msgid ""
-"Filters results by the backup status ('creating', 'available', 'deleting', "
-"'error', 'restoring' or 'error_restoring')"
-msgstr ""
-"Yedek durumuna göre sonuçları filtrele ('oluşturuluyor', 'kullanılabilir', "
-"'siliniyor', 'hata' veya 'geri yüklenirken hata')"
-
 msgid "Filters results by the volume which they backup (name or ID)"
 msgstr "Yedeklenen disk bölümüne göre sonuçları filtrele (isim veya ID)"
 
 msgid "Fixed IP address mapped to the floating IP"
 msgstr "Sabit IP adres yüzen IP adresi ile eşleşti"
 
-msgid "Fixed IP address to associate with this floating IP address"
-msgstr "Bu kayan IP adresi ile ilişkili sabit IP adresi"
-
 msgid "Fixed IP address to remove from the server (IP only)"
 msgstr "Sunucudan kaldırılacak sabit IP adresi (sadece IP)"
 
@@ -2687,15 +2257,9 @@ msgstr "Silinecek flavor(lar) (isim veya
 msgid "Floating IP address"
 msgstr "Yüzen IP adresi"
 
-msgid "Floating IP address to assign to server (IP only)"
-msgstr "Sunucuya atanacak kayan IP adresi (sadece IP)"
-
 msgid "Floating IP address to remove from server (IP only)"
 msgstr "Sunucudan kaldırılacak kayan IP adresi (sadece IP)"
 
-msgid "Floating IP to associate (IP address or ID)"
-msgstr "İlişkilendirilecek yüzen IP adresi (IP adres veya ID)"
-
 msgid "Floating IP to disassociate (IP address or ID)"
 msgstr "Bağlantıyı kesmek için kayan IP (IP adresi veya kimliği)"
 
@@ -2709,9 +2273,6 @@ msgid "Floating ip pool operations are o
 msgstr ""
 "Yüzen IP havuz işlemleri sadece Hesaplama v2 ağı için kullanılabilirdir."
 
-msgid "Force down service"
-msgstr "Servisi durmaya zorla"
-
 msgid "Force image change if volume is in use (only meaningful with --volume)"
 msgstr ""
 "Disk bölümü kullanımda ise imajı değişmeye zorla (sadece --volume ile "
@@ -2723,9 +2284,6 @@ msgstr ""
 "Disk bölümü kullanımda ise imaj oluşturmaya zorla (sadece --volume ile "
 "anlamlıdır)"
 
-msgid "Force up service"
-msgstr "Servisi açılmaya zorla"
-
 msgid "Freeze and disable the specified volume host"
 msgstr "Belirtilen disk bölümü sunucusunu dondur ve devre dışı bırak"
 
@@ -2753,9 +2311,6 @@ msgstr "Silinecek grup(lar) (isim veya I
 msgid "Helper class capable of reading rules from files"
 msgstr "Yardımcı sınıf kuralları dosyadan okuyabilir"
 
-msgid "Hints for the scheduler (optional extension)"
-msgstr "Zamanlayıcı için ipuçları (isteğe bağlı eklenti)"
-
 msgid "Host to add to <aggregate>"
 msgstr "<aggregate> için eklenecek sunucu"
 
@@ -2802,25 +2357,12 @@ msgstr "Bu imajı oluşturmak için kull
 msgid "ID of the agent"
 msgstr "Ajanın ID'si"
 
-msgid "IP address to add to server (name only)"
-msgstr "Sunucuya eklenecek IP adresi (sadece isim)"
-
-msgid "IP address to remove from server (name only)"
-msgstr "Sunucudan kaldırılacak IP adresi (sadece isim)"
-
 msgid "IP protocol (icmp, tcp, udp; default: tcp)"
 msgstr "IP protokolü (icmp, tcp, udp; varsayılan: tcp)"
 
 msgid "IP version (default is 4)"
 msgstr "IP sürümü (varsayılan 4)"
 
-msgid ""
-"IP version (default is 4).  Note that when subnet pool is specified, IP "
-"version is determined from the subnet pool and this option is ignored."
-msgstr ""
-"IP sürümü (varsayılan 4).  Alt ağ havuzu belirtildiğinde, IP sürümü alt ağ "
-"havuzundan belirlenir ve bu seçenek göz ardı edilir."
-
 msgid "IPv4 subnet for fixed IPs (in CIDR notation)"
 msgstr "Sabit IP'ler için IPv4 alt ağı (CIDR gösteriminde)"
 
@@ -2871,16 +2413,6 @@ msgstr ""
 "Belirtilirse, disk bölümü durumu kilitlenir ve geçiş işleminin iptal "
 "edilmesine izin vermeyecektir (muhtemelen başka bir işlemle)"
 
-msgid ""
-"If specified, the volume state will not be locked and the a migration can be "
-"aborted (default) (possibly by another operation)"
-msgstr ""
-"Belirtilirse, disk bölümü durumu kilitlenmez ve bir taşıma işlemi iptal "
-"edilebilir (varsayılan) (muhtemelen başka bir işlemle)"
-
-msgid "If topology exists returns the topology's information (Default)"
-msgstr "Topoloji var ise, topolojinin bilgisini döndürür (Varsayılan)"
-
 #, python-format
 msgid "Image %(id)s was %(status)s."
 msgstr "%(id)s imaj %(status)s idi."
@@ -2892,9 +2424,6 @@ msgstr "İmaj API sürümü, öntanıml
 msgid "Image ID to reserve"
 msgstr "Ayrılacak imaj ID'si"
 
-msgid "Image can be shared"
-msgstr "İmaj paylaşılabilir"
-
 #, python-format
 msgid ""
 "Image container format. The supported options are: %(option_list)s. The "
@@ -2925,9 +2454,6 @@ msgstr ""
 msgid "Image hash used for verification"
 msgstr "Doğrulama için kullanılan imaj özeti"
 
-msgid "Image is accessible to the community"
-msgstr "İmaj topluluk tarafından erişilebilir"
-
 msgid "Image is accessible to the public"
 msgstr "İmaj genele açıktır"
 
@@ -2974,9 +2500,6 @@ msgstr "Tüm projeleri dahil et (sadece
 msgid "Include remote IP prefix from traffic count (default)"
 msgstr "Trafik sayımından uzak IP önekini ekle (varsayılan)"
 
-msgid "Include reservations count [only valid with --absolute]"
-msgstr "Rezervasyon sayısını ekle [sadece --absolute ile geçerlidir]"
-
 msgid ""
 "Incorrect set of arguments provided. See openstack --help for more details"
 msgstr ""
@@ -2987,21 +2510,9 @@ msgid "Ingress traffic direction from th
 msgstr "Projenin bakış açısından gelen trafik yönü"
 
 #, python-format
-msgid "Invalid argument %s, characters ',' and '=' are not allowed"
-msgstr "%s geçersiz değişken, ',' ve '=' karakterlerine izin verilmiyor"
-
-#, python-format
 msgid "Invalid changes-since value: %s"
 msgstr "Geçersiz değişiklikler-şu değerden beri:%s"
 
-#, python-format
-msgid ""
-"Invalid nic argument '%s'. Nic arguments must be of the form --nic <net-"
-"id=net-uuid,v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,port-id=port-uuid>."
-msgstr ""
-"Geçersiz '%s' nic argümanı, Nic argümanları --nic <net-id=net-uuid,v4-fixed-"
-"ip=ip-addr,v6-fixed-ip=ip-addr,port-id=port-uuid> biçiminde olmalıdır."
-
 msgid "Issue new token"
 msgstr "Yeni jeton yayınla"
 
@@ -3013,18 +2524,9 @@ msgstr "%(private_key)s anahtar dosyası
 msgid "Key file %(public_key)s not found: %(exception)s"
 msgstr "%(public_key)s anahtar dosyası bulunamadı: %(exception)s"
 
-msgid "Keypair to inject into this server (optional extension)"
-msgstr "Bu sunucuya enjekte etmek için anahtarlık (isteğe bağlı uzantı)"
-
 msgid "Label to associate with this metering rule (name or ID)"
 msgstr "Bu ölçüm kuralı ile ilişkili etiket (isim veya ID)"
 
-msgid "Limit the number of containers returned"
-msgstr "İade edilen kap sayısını sınırla"
-
-msgid "Limit the number of objects returned"
-msgstr "Döndürülen nesnelerin sayısını sınırla"
-
 #, python-format
 msgid "List %s which have all given tag(s) (Comma-separated list of tags)"
 msgstr ""
@@ -3069,9 +2571,6 @@ msgstr "QoS özelliklerini listele"
 msgid "List Service Providers"
 msgstr "Servis Sağlayıcıları listele"
 
-msgid "List a project's resources"
-msgstr "Bir projenin kaynaklarını listele"
-
 msgid "List accessible domains"
 msgstr "Erişilebilir alanları listele"
 
@@ -3126,21 +2625,12 @@ msgstr "Kullanılabilirlik alanlarını
 msgid "List available images"
 msgstr "Kullanılabilir imajlar listesi"
 
-msgid "List backups"
-msgstr "Yedekleri listele"
-
-msgid "List compute agents"
-msgstr "Hesaplama ajanlarını listele"
-
 msgid "List compute availability zones"
 msgstr "Hesaplama kullanılabilirlik alanlarını listele"
 
 msgid "List compute quota"
 msgstr "Hesaplama kotasını listele"
 
-msgid "List compute services"
-msgstr "Hesaplama servislerini listele"
-
 msgid "List consistency group snapshots."
 msgstr "Tutarlılık grubu anlık görüntülerini listele."
 
@@ -3219,9 +2709,6 @@ msgstr "Verilen duruma göre yüzen IP(l
 msgid "List groups"
 msgstr "Grupları listele"
 
-msgid "List hosts"
-msgstr "Sunucuları listele"
-
 msgid "List hypervisors"
 msgstr "Yönetici arakatman listesi"
 
@@ -3253,13 +2740,6 @@ msgstr ""
 "Verilen eyleme göre ağ RBAC ilkelerini listele (\"access_as_external\" veya "
 "\"access_as_shared\")"
 
-msgid ""
-"List network RBAC policies according to given object type (\"qos_policy\" or "
-"\"network\")"
-msgstr ""
-"Verilen nesne türüne göre Ağ RBAC politikalarının listesi (\"qos_policy\" "
-"veya \"network\")"
-
 msgid "List network agents"
 msgstr "Ağ ajanlarını listele"
 
@@ -3300,13 +2780,6 @@ msgstr "Ağları fiziksel ağın adına
 msgid "List networks according to their name"
 msgstr "Ağları isimlerine göre listele"
 
-msgid ""
-"List networks according to their physical mechanisms. The supported options "
-"are: flat, geneve, gre, local, vlan, vxlan."
-msgstr ""
-"Ağları fiziksel mekanizmalarına göre listeleyin. Desteklenen seçenekler "
-"şunlardır: flat, geneve, gre, local, vlan, vxlan."
-
 msgid "List networks according to their project (name or ID)"
 msgstr "Projelerine göre ağları listele (isim veya ID)"
 
@@ -3333,15 +2806,6 @@ msgstr "Çıktıda verilen adın sadece
 msgid "List only agents running on the specified host"
 msgstr "Yalnızca belirtilen ana bilgisayarda çalışan ajanları listele"
 
-msgid ""
-"List only agents with the specified agent type. The supported agent types "
-"are: bgp, dhcp, open-vswitch, linux-bridge, ofa, l3, loadbalancer, metering, "
-"metadata, macvtap, nic."
-msgstr ""
-"Yalnızca belirtilen aracı türü olan aracıları listeleyin. Desteklenen aracı "
-"türleri şunlardır: bgp, dhcp, open-vswitch, linux-bridge, ofa, l3, "
-"loadbalancer, metering, metadata, macvtap, nic."
-
 msgid "List only ports attached to this router (name or ID)"
 msgstr ""
 "Yalnızca bu yönlendiriciye bağlı bağlantı noktalarını listeleyin (adı veya "
@@ -3382,16 +2846,6 @@ msgstr "Sadece genele açık imajları l
 msgid "List only public types"
 msgstr "Sadece genele açık türleri listele"
 
-msgid ""
-"List only servers changed after a certain point of time. The provided time "
-"should be an ISO 8061 formatted time. ex 2016-03-04T06:27:59Z ."
-msgstr ""
-"Yalnızca belirli bir zaman noktasından sonra sunucuları listeleyin. Verilen "
-"süre bir ISO 8061 biçiminde olmalıdır. Örn 2016-03-04T06: 27: 59Z ."
-
-msgid "List only shared images"
-msgstr "Sadece paylaşılan imajları listele"
-
 msgid "List only specified service (name only)"
 msgstr "Sadece belirtilen servisleri listele (sadece isim)"
 
@@ -3403,23 +2857,6 @@ msgstr ""
 msgid "List only subnet pools of given name in output"
 msgstr "Verilen isimdeki sadece altağ havuzlarını çıktıda listele"
 
-msgid ""
-"List only subnets of a given service type in output e.g.: network:"
-"floatingip_agent_gateway. Must be a valid device owner value for a network "
-"port (repeat option to list multiple service types)"
-msgstr ""
-"Çıktıda verilen servisin sadece altağlarını listele örn: network:"
-"floatingip_agent_gateway. Bir ağ bağlantı noktası için geçerli bir aygıt "
-"sahibi değeri olmalıdır (birden fazla servis türü listelemek için seçeneği "
-"tekrarla)"
-
-msgid ""
-"List only subnets of given IP version in output.Allowed values for IP "
-"version are 4 and 6."
-msgstr ""
-"Verilen IP sürümünün sadece altağlarını çıktıda listele. IP sürümü için izin "
-"verilen sürümler 4 ve 6."
-
 msgid "List only subnets of given gateway IP in output"
 msgstr "Verilen geçit IP'sinin sadece alt ağlarını çıktıda listele"
 
@@ -3427,13 +2864,6 @@ msgid "List only subnets of given name i
 msgstr "Verilen isimdeki sadece altağları çıktıda listele"
 
 msgid ""
-"List only subnets of given subnet range (in CIDR notation) in output e.g.: --"
-"subnet-range 10.10.0.0/16"
-msgstr ""
-"Verilen alt ağ aralığında (CIDR notasyonu ile) sadece altağları çıktıda "
-"listele örn: --subnet-range 10.10.0.0/16"
-
-msgid ""
 "List only subnets which belong to a given network in output (name or ID)"
 msgstr "Verilen bir ağa ait sadece altağları çıktıda listele (isim veya ID)"
 
@@ -3462,22 +2892,6 @@ msgstr ""
 "Yetkilendirilmiş kullanıcı için projeleri listele. Diğer filtrelerin yerini "
 "alır."
 
-msgid "List qos policies according to their project (name or ID)"
-msgstr "Projelerine göre QoS politikalarını listele (isim veya ID)"
-
-msgid "List qos policies not shared between projects"
-msgstr "Projeler arasında paylaştırılmayan qos ilkelerini listele"
-
-msgid "List qos policies shared between projects"
-msgstr "Projeler arasında paylaşılan qos politikalarını listele"
-
-msgid "List quotas for all projects with non-default quota values"
-msgstr ""
-"Varsayılan olmayan kota değerlerine sahip tüm projelerin kotalarını listeleme"
-
-msgid "List recent events of a server"
-msgstr "Bir sunucunun son olaylarını listele"
-
 msgid "List recognized commands by group"
 msgstr "Grup tarafından tanınan komutları listele"
 
@@ -3511,15 +2925,6 @@ msgstr "Gelen ağ trafiğine uygulanan k
 msgid "List rules applied to outgoing network traffic"
 msgstr "Giden ağ trafiğine uygulanan kuralları listele"
 
-msgid ""
-"List rules by the IP protocol (ah, dhcp, egp, esp, gre, icmp, igmp, ipv6-"
-"encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, ipv6-opts, ipv6-route, ospf, pgm, "
-"rsvp, sctp, tcp, udp, udplite, vrrp and integer representations [0-255])."
-msgstr ""
-"Kuralları IP protokolüne göre listele (ah, dhcp, egp, esp, gre, icmp, igmp, "
-"ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, ipv6-opts, ipv6-route, ospf, "
-"pgm, rsvp, sctp, tcp, udp, udplite, vrrp ve tam sayı gösterimleri [0-255])"
-
 msgid "List security group rules"
 msgstr "Güvenlik grubu kurallarını listele"
 
@@ -3547,9 +2952,6 @@ msgstr "Servis katalogundaki servisleri
 msgid "List services on specified host (name only)"
 msgstr "Belirtilen sunucu üzerindeki servisleri listele (sadece isim)"
 
-msgid "List snapshots"
-msgstr "Anlık görüntüleri listele"
-
 msgid "List subnet pools"
 msgstr "Altağ havuzlarını listele"
 
@@ -3585,9 +2987,6 @@ msgstr "Varsayılan disk bölümü tür
 msgid "List trusts"
 msgstr "Güvenleri listele"
 
-msgid "List user-role assignments"
-msgstr "Kullanıcı rol atamalarını listele"
-
 msgid "List users"
 msgstr "Kullanıcıları listele"
 
@@ -3609,76 +3008,12 @@ msgstr "Disk bölümü türlerini listel
 msgid "List volumes"
 msgstr "Disk bölümlerini listele"
 
-msgid ""
-"Listing assignments using role list is deprecated as of the Newton release. "
-"Use role assignment list --user <user-name> --project <project-name> --names "
-"instead."
-msgstr ""
-"Rol listesi kullanarak liste atamaları, Newton sürümünden itibaren "
-"kullanımdan kaldırılmıştır. Onun yerine rol atama listesi --user <user-name> "
-"--project <project-name> --names komutunu kullanın."
-
-msgid ""
-"Listing assignments using role list is deprecated. Use role assignment list "
-"--group <group-name> --domain <domain-name> --names instead."
-msgstr ""
-"Rol listesini kullanarak liste atamaları kullanımdan kaldırıldı. Onun yerine "
-"role assignment list --group <group-name> --domain <domain-name> --names "
-"kullanın."
-
-msgid ""
-"Listing assignments using role list is deprecated. Use role assignment list "
-"--group <group-name> --project <project-name> --names instead."
-msgstr ""
-"Rol listesini kullanarak liste atamaları kullanımdan kaldırıldı. Onun yerine "
-"role assignment list --group <group-name> --project <project-name> --names "
-"kullanın."
-
-msgid ""
-"Listing assignments using role list is deprecated. Use role assignment list "
-"--user <user-name> --domain <domain-name> --names instead."
-msgstr ""
-"Rol listesini kullanarak liste atamaları kullanımdan kaldırıldı. Bunun "
-"yerine role assignment list --user <user-name> --domain <domain-name> --"
-"names kullanın."
-
-msgid ""
-"Listing assignments using role list is deprecated. Use role assignment list "
-"--user <user-name> --domain default --names instead."
-msgstr ""
-"Rol listesini kullanarak liste atamaları kullanımdan kaldırıldı. Onun yerine "
-"role assignment list --user <user-name> --domain default --names kullanın."
-
-msgid ""
-"Listing assignments using role list is deprecated. Use role assignment list "
-"--user <user-name> --project <project-name> --names instead."
-msgstr ""
-"Rol listesini kullanarak liste atamaları kullanımdan kaldırıldı. Bunun "
-"yerine, role assignment list --user <user-name> --project <project-name> --"
-"names kullanın."
-
-msgid ""
-"Listing assignments using user role list is deprecated as of the Newton "
-"release. Use role assignment list --user <user-name> --project <project-"
-"name> --names instead."
-msgstr ""
-"Atamaları kullanıcı rol listesi kullanarak listelemek Newton sürümünden "
-"itibaren kullanımdan kaldırılmıştır. Onun yerine role assignment list --user "
-"<user-name> --project <project-name> --names komutunu kullanın."
-
 msgid "Lists all volume transfer requests."
 msgstr "Tüm disk bölümü aktarım isteklerini listele."
 
 msgid "Local filename(s) to upload"
 msgstr "Yüklenecek yerel dosya ad(lar)ı"
 
-msgid "Lock server(s). A non-admin user will not be able to execute actions"
-msgstr ""
-"Sunucu(ları/yu) kilitle. Yönetici olmayan kullanıcılar işlem yapamayacaktır."
-
-msgid "Login name (ssh -l option)"
-msgstr "Giriş adı (ssh -l seçeneği)"
-
 msgid "MAC address of this port (admin only)"
 msgstr "Bu bağlantı noktasının MAC adresi (yalnızca yönetici)"
 
@@ -3729,45 +3064,12 @@ msgstr "Disk bölümünü ön yüklemesi
 msgid "Maximum bandwidth in kbps"
 msgstr "En büyük bant genişliği kbps cinsinden"
 
-msgid "Maximum burst in kilobits, 0 means automatic"
-msgstr "Kilo bit cinsinden en büyük atış, 0 otomatik anlamına gelir"
-
-msgid "Maximum number of backups to display"
-msgstr "En fazla gösterilecek yedek sayısı "
-
-msgid "Maximum number of flavors to display"
-msgstr "Gösterilecek en fazla flavor sayısı"
-
-msgid "Maximum number of images to display."
-msgstr "Gösterilecek en fazla imaj sayısı."
-
-msgid ""
-"Maximum number of servers to display. If limit equals -1, all servers will "
-"be displayed. If limit is greater than 'osapi_max_limit' option of Nova API, "
-"'osapi_max_limit' will be used instead."
-msgstr ""
-"Gösterilecek en fazla sunucu sayısı. Eğer sınır -1'e eşitse, tüm sunucular "
-"gösterilir. Eğer limit Nova API'nın 'osapi_max_limit' seçeneğinden daha "
-"büyükse, onun yerine 'osapi_max_limit' kullanılacaktır."
-
 msgid "Maximum number of servers to launch (default=1)"
 msgstr "Başlatılması gereken en fazla sunucu sayısı (varsayılan=1)"
 
-msgid "Maximum number of snapshots to display"
-msgstr "Gösterilecek en büyük anlık görüntü sayısı"
-
-msgid "Maximum number of volumes to display"
-msgstr "Gösterilecek en çok disk bölümü sayısı"
-
 msgid "Memory size in MB (default 256M)"
 msgstr "MB cinsinden bellek boyutu (varsayılan 256M)"
 
-msgid ""
-"Metainfo for the flavor profile. This becomes required if --driver is "
-"missing and vice versa"
-msgstr ""
-"Flavor profili için Metainfo. --driver eksikse bu gereklidir ya da tam tersi"
-
 msgid "Meter rule (ID only)"
 msgstr "Ölçek kuralı (sadece ID)"
 
@@ -3780,9 +3082,6 @@ msgstr "Silinecek ölçek (isim veya ID)
 msgid "Meter to display (name or ID)"
 msgstr "Gösterilecek ölçek (isim veya ID)"
 
-msgid "Migrate server to different host"
-msgstr "Farklı konakçıya sunucuyu göç ettir"
-
 msgid "Migrate volume to a new host"
 msgstr "Disk bölümünü yeni bir sunucuya göç ettir"
 
@@ -3872,9 +3171,6 @@ msgid ""
 "Name of the physical network over which the virtual network is implemented"
 msgstr "Sanal ağın üzerinde uygulandığı fiziksel ağın adı"
 
-msgid "Name of the snapshot"
-msgstr "Anlık görüntü ismi"
-
 msgid "Name of this port"
 msgstr "Bu bağlantı noktasının ismi"
 
@@ -3884,12 +3180,6 @@ msgstr "Disk bölümü anabilgisayarın
 msgid "Name or ID of project to show usage for"
 msgstr "Kullanımı gösterilecek projenin isim veya ID'si"
 
-msgid "Name or ID of security group to remove from server"
-msgstr "Sunucudan kaldırılacak güvenlik grubunun isim veya ID'si"
-
-msgid "Name or ID of server to use"
-msgstr "Kullanılacak sunucunun isim veya ID'si"
-
 #, python-format
 msgid "Network API version, default=%s (Env: OS_NETWORK_API_VERSION)"
 msgstr "Ağ API sürümü, varsayılan=%s (Env: OS_NETWORK_API_VERSION)"
@@ -3948,9 +3238,6 @@ msgstr "Bir ajandan kaldırılacak ağ (
 msgid "Network to display (name or ID)"
 msgstr "Gösterilecek ağ (isim veya ID)"
 
-msgid "Network to fetch an IP address from (name or ID)"
-msgstr "IP adresi çekilecek ağ (isim veya ID)"
-
 msgid "Network to modify (name or ID)"
 msgstr "Düzenlenecek ağ (isim veya ID)"
 
@@ -3981,21 +3268,6 @@ msgstr "Yeni adres kapsam ismi"
 msgid "New aggregate name"
 msgstr "Yeni küme ismi"
 
-msgid "New backup description"
-msgstr "Yeni yedek açıklaması"
-
-msgid "New backup name"
-msgstr "Yeni yedek ismi"
-
-msgid ""
-"New backup state (\"available\" or \"error\") (admin only) (This option "
-"simply changes the state of the backup in the database with no regard to "
-"actual status, exercise caution when using)"
-msgstr ""
-"Yeni yedek durumu (\"kullanılabilir\" veya \"hata\") (sadece yönetici) (Bu "
-"seçenek, veritabanındaki yedeklemenin durumunu gerçek durumu dikkate almadan "
-"değiştirir, kullanırken dikkatli olun.)"
-
 msgid "New consistency group description"
 msgstr "Yeni tutarlılık grubu açıklaması"
 
@@ -4109,9 +3381,6 @@ msgstr "Yeni sunucu grup ismi"
 msgid "New server name"
 msgstr "Yeni sunucu ismi"
 
-msgid "New server state (valid value: active, error)"
-msgstr "Yeni sunucu durumu (geçerli değer: aktif, hata)"
-
 msgid "New service description"
 msgstr "Yeni servis tanımı"
 
@@ -4218,10 +3487,6 @@ msgstr "'%s' türünde, isminde veya ID'
 msgid "No service with a type, name or ID of '%s' exists."
 msgstr "'%s' türünde, isminde veya ID'si ile bir servis bulunamadı."
 
-#, python-format
-msgid "No tags associated with the %s"
-msgstr "%s ile ilişkilendirilmiş hiç etiket yok"
-
 msgid "Number of backups to keep (default: 1)"
 msgstr "Tutulacak yedekleme sayısı (varsayılan: 1)"
 
@@ -4256,9 +3521,6 @@ msgstr "Bir veya birden fazla ayar kald
 msgid "Only an authorized user may issue a new token."
 msgstr "Yalnızca yetkili bir kullanıcı yeni bir jeton verebilir."
 
-msgid "Only display deleted servers (Admin only)."
-msgstr "Sadece silinen sunucuları göster (sadece admin)."
-
 msgid "Only return hosts in the availability zone"
 msgstr "Sadece kullanılabilirlik bölgesindeki sunucuları döndürür"
 
@@ -4277,9 +3539,6 @@ msgstr "Işletim sistemi dağıtım sür
 msgid "Optional backup container name"
 msgstr "Seçimli yedek kap ismi"
 
-msgid "Options in ssh_config(5) format (ssh -o option)"
-msgstr "ssh_config(5) biçemi içerisindeki seçenekler (ssh -o seçeneği)"
-
 msgid "Original user password"
 msgstr "Orijinal kullanıcı parolası"
 
@@ -4298,18 +3557,12 @@ msgstr "Parolalar eşleşmedi, parola de
 msgid "Pause server(s)"
 msgstr "Sunucu(ları/yu) durdur"
 
-msgid "Perform a block live migration"
-msgstr "Bir blok gerçek göç gerçekleştir"
-
 msgid "Perform a hard or soft server reboot"
 msgstr "Sert veya yumuşak sunucu yeniden başlatmayı gerçekleştir"
 
 msgid "Perform a hard reboot"
 msgstr "Sert yeniden başlatmayı gerçekleştir"
 
-msgid "Perform a shared live migration (default)"
-msgstr "Paylaşımlı canlı göç gerçekleştir (varsayılan)"
-
 msgid "Perform a soft reboot"
 msgstr "Yumuşak yeniden başlatmayı gerçekleştir"
 
@@ -4380,9 +3633,6 @@ msgstr "İmajı silinmekten koru"
 msgid "Print image size in a human-friendly format."
 msgstr "İmaj boyutunu insan dostu bir biçimde bastırın."
 
-msgid "Private key file (ssh -i option)"
-msgstr "Gizli anahtar dosyası (ssh -i seçeneği)"
-
 msgid "Project and User must be specified"
 msgstr "Proje ve kullanıcı belirtilmeli"
 
@@ -4392,15 +3642,9 @@ msgstr "Devredilen proje (isim veya ID)
 msgid "Project description"
 msgstr "Proje açıklaması"
 
-msgid "Project must be specified"
-msgstr "Proje belirtilmek zorunda"
-
 msgid "Project that consumer wants to access (name or ID) (required)"
 msgstr "Alıcının erişmek istediği proje (isim veya ID) (gerekli)"
 
-msgid "Project to associate with image (name or ID)"
-msgstr "İmaj ile ilişkili proje (isim veya ID)"
-
 msgid "Project to clean (name or ID)"
 msgstr "Temizlenecek proje (isim veya ID)"
 
@@ -4525,16 +3769,6 @@ msgstr ""
 msgid "Public or private key to display (name only)"
 msgstr "Gösterilecek açık veya kapalı anahtar (sadece isim)"
 
-msgid "Put server in rescue mode"
-msgstr "Sunucuyu kurtarma kipine getir"
-
-msgid ""
-"Python module path to driver. This becomes required if --metainfo is missing "
-"and vice versa"
-msgstr ""
-"Python modülünün sürücüye yolu. --metainfo eksikse bu gereklidir ya da tam "
-"tersi"
-
 msgid "QoS policy that contains the rule (name or ID)"
 msgstr "Kuralı içeren QoS politikası (isim veya ID)"
 
@@ -4607,18 +3841,12 @@ msgstr "Düzenlenecek bölge"
 msgid "Regular expression to match IP addresses"
 msgstr "IP adresleriyle eşleşen düzenli ifadeler"
 
-msgid "Regular expression to match IPv6 addresses"
-msgstr "IPv6 adresleriyle eşleşen düzenli ifadeler"
-
 msgid "Regular expression to match instance name (admin only)"
 msgstr "Sunucu adıyla eşleşen düzenli ifadeler (yalnızca yönetici)"
 
 msgid "Regular expression to match names"
 msgstr "Adları eşleştirmek için düzenli ifadeler"
 
-msgid "Reject the image membership"
-msgstr "İmaj üyeliğini red et"
-
 msgid ""
 "Remote IDs to associate with the Identity Provider (repeat option to provide "
 "multiple values)"
@@ -4626,13 +3854,6 @@ msgstr ""
 "Kimlik Sağlayıcısı ile ilişkilendirilecek uzak kimlikler (birden fazla değer "
 "sağlamak için seçeneği tekrarlayın)"
 
-msgid ""
-"Remote IP address block (may use CIDR notation; default for IPv4 rule: "
-"0.0.0.0/0)"
-msgstr ""
-"Uzak IP adres bloğu (CIDR notasyonu kullanılabilir; IPv4 kuralı için "
-"varsayılan: 0.0.0.0/0)"
-
 msgid "Remote security group (name or ID)"
 msgstr "Uzak güvenlik grubu (isim veya ID)"
 
@@ -4740,43 +3961,24 @@ msgstr "Sunucudan güvenlik grubunu kald
 msgid "Remove service profile from network flavor"
 msgstr "Servis profilini ağ flavor'ından kaldır"
 
-msgid ""
-"Remove subnet pool prefixes (in CIDR notation). (repeat option to unset "
-"multiple prefixes)."
-msgstr ""
-"Alt ağ havuzu öneklerini kaldır (CIDR gösteriminde). (Birden fazla önekin "
-"ayarını kaldırmak için seçeneği tekrarlayın)."
-
 msgid "Remove the QoS policy attached to the port"
 msgstr "Bağlantı noktasına eklenmiş QoS politikasını kaldır"
 
 msgid "Remove the QoS policy attached to this network"
 msgstr "Bu ağa bağlı QoS politikasını kaldırın"
 
-msgid "Remove the encryption type for this volume type (admin oly)"
-msgstr "Bu disk bölümü için şifreleme türünü sil (sadece yönetici)"
-
 msgid "Remove the encryption type for this volume type (admin only)"
 msgstr "Bu disk bölümü türü için şifreleme türü kaldırıldı (sadece yönetici)"
 
 msgid "Remove user from group"
 msgstr "Kullanıcıyı gruptan kaldır"
 
-msgid "Remove volume from server"
-msgstr "Disk bölümünü sunucudan kaldır"
-
 msgid "Remove volume(s) from consistency group"
 msgstr "Tutarlılık grubundan disk bölümlerini sil"
 
-msgid "Removes a role assignment from domain/project : user/group"
-msgstr "Bir rol atamasını alan/proje : kullanıcı/gruptan kaldırır."
-
 msgid "Removes volume type access to project (name or ID) (admin only)"
 msgstr "Projeye disk türü erişimini kaldırır (isim veya ID) (sadece yönetici)"
 
-msgid "Replicated volume to clone (name or ID)"
-msgstr "Klonlanacak yinelenmiş disk bölümü (isim veya ID)"
-
 msgid "Request ID of the event to show (ID only)"
 msgstr "Gösterilecek olayın ID'sini iste (sadece ID)"
 
@@ -4795,15 +3997,9 @@ msgstr "İmaj üyeliğini 'beklemede' ol
 msgid "Resize server to specified flavor"
 msgstr "Sunucuyu belirtilen flavor'a yeniden boyutlandır"
 
-msgid "Restore backup"
-msgstr "Yedeği yeniden yükle"
-
 msgid "Restore server from rescue mode"
 msgstr "Kurtarma kipinden sunucuyu onar"
 
-msgid "Restore server state before resize"
-msgstr "Sunucu durumunu yeniden boyutlandırmadan önceki haline geri getir"
-
 msgid "Restore server(s)"
 msgstr "Sunucu(ları/yu) onar "
 
@@ -4828,13 +4024,6 @@ msgstr "Mevcut rolü döndür"
 msgid "Return existing user"
 msgstr "Mevcut kullanıcıyı döndür"
 
-msgid ""
-"Return the auto allocated topology for a given project. Default is current "
-"project"
-msgstr ""
-"Belirli bir proje için otomatik olarak ayrılan topolojiyi döndürür. "
-"Varsayılan geçerli projedir"
-
 #, python-format
 msgid "Returning existing domain %s"
 msgstr "Mevcut alanı döndür %s"
@@ -4909,15 +4098,6 @@ msgstr ""
 msgid "Roll up items with <delimiter>"
 msgstr "Elemanları <delimiter> ile toparla"
 
-msgid ""
-"Route to be removed from this subnet e.g.: destination=10.10.0.0/16,"
-"gateway=192.168.71.254 destination: destination subnet (in CIDR notation) "
-"gateway: nexthop IP address (repeat option to unset multiple host routes)"
-msgstr ""
-"Bu altağdan silinecek yön örn: hedef=10.10.0.0/16,geçit=192.168.71.254 hedef:"
-"hedef altağ (CIDR notasyonunda) geçit: bir sonraki uğranacak IP adresi "
-"(birden fazla sunucu yönü ayarı kaldırmak için seçeneği tekrar et)"
-
 #, python-format
 msgid "Router does not contain route %s"
 msgstr "Yönlendirici %s yönünü içermiyor"
@@ -4949,23 +4129,6 @@ msgstr "Alt ağın ekleneceği yönlendi
 msgid "Router(s) to delete (name or ID)"
 msgstr "Silinecek yönlendirici(ler) (isim veya ID)"
 
-msgid ""
-"Routes associated with the router destination: destination subnet (in CIDR "
-"notation) gateway: nexthop IP address (repeat option to set multiple routes)"
-msgstr ""
-"Yönlendirici hedefi ile ilişkili yönlendiriciler: hedef altağ (CIDR "
-"notasyonunda) geçit: bir sonraki atlanacak IP adresi (birden fazla "
-"yönlendirici ayarlamak için seçeneği tekrarla)"
-
-msgid ""
-"Routes to be removed from the router destination: destination subnet (in "
-"CIDR notation) gateway: nexthop IP address (repeat option to unset multiple "
-"routes)"
-msgstr ""
-"Yönlendirici hedefinden kaldırılacak yönlendiriciler: hedef alt ağ (CIDR "
-"notasyonuyla) geçit: atlanacak sonraki IP adresi (birden fazla "
-"yönlendiricinin ayarını kaldırmak için seçeneği tekrarla)"
-
 #, python-format
 msgid "Rule ID %(rule_id)s not found"
 msgstr "%(rule_id)s kural ID'si bulunamadı"
@@ -4976,10 +4139,6 @@ msgstr "Gelen ağ trafiğine uygulanacak
 msgid "Rule applies to outgoing network traffic"
 msgstr "Dışarıya doğru ağ trafiğine uygulanacak kural"
 
-#, python-format
-msgid "Rule type \"%(rule_type)s\" only requires arguments %(args)s"
-msgstr "\"%(rule_type)s\" kural türü sadece %(args)s argümanlarını gerektirir"
-
 msgid "SSH to server"
 msgstr "Sunucuya SSH ile bağlan"
 
@@ -4992,29 +4151,6 @@ msgstr "Kap içeriğini yerel olarak kay
 msgid "Save object locally"
 msgstr "Nesneyi yerel olarak kaydet"
 
-msgid ""
-"Scale server to a new flavor.\n"
-"\n"
-"A resize operation is implemented by creating a new server and copying the\n"
-"contents of the original disk into a new one. It is also a two-step process "
-"for\n"
-"the user: the first is to perform the resize, the second is to either "
-"confirm\n"
-"(verify) success and release the old server, or to declare a revert to "
-"release\n"
-"the new server and restart the old one."
-msgstr ""
-"Sunucuyu yeni bir flavor'a ölçekle.\n"
-"\n"
-"Bir yeniden boyutlandırma işlemi yeni bir sunucu oluşturma ve orijinal \n"
-"diskteki içeriğin yeni bir tanesine kopyalanması ile gerçekleştirilir. Bu "
-"ayrıca\n"
-"kullanıcı için iki adımlı bir süreçtir: birincisi yeniden boyutlandırmayı "
-"gerçekleştirmek,\n"
-"ikincisi ya başarılı olduğunu doğrulamak ve eski sunucuyu silmek, ya da "
-"yenisini silip\n"
-"eskisini yeniden başlatma isteğini belirtmek."
-
 msgid "Search by flavor (name or ID)"
 msgstr "Flavor'a göre ara (isim veya ID)"
 
@@ -5030,9 +4166,6 @@ msgstr "Projeye göre ara (sadece yönet
 msgid "Search by server status"
 msgstr "Sunucu durumuna göre ara"
 
-msgid "Search by user (admin only) (name or ID)"
-msgstr "Kullanıcıya göre ara (sadece yönetici) (isim veya ID)"
-
 msgid "Secret associated with <request-key> (required)"
 msgstr "<request-key> ile ilişkili gizli anahtar (gerekli)"
 
@@ -5045,16 +4178,6 @@ msgstr "Gösterilecek güvenlik grubu ku
 msgid "Security group rule(s) to delete (ID only)"
 msgstr "Silinecek güvenlik grubu kuralları (sadece ID)"
 
-msgid "Security group to add (name or ID)"
-msgstr "Eklenecek güvenlik grubu (isim veya ID)"
-
-msgid ""
-"Security group to assign to this server (name or ID) (repeat option to set "
-"multiple groups)"
-msgstr ""
-"Bu sunucuya atanan güvenlik grubu (isim veya ID) (birden fazla grup "
-"ayarlamak için seçeneği tekrar edin)"
-
 msgid ""
 "Security group to associate with this port (name or ID) (repeat option to "
 "set multiple security groups)"
@@ -5086,9 +4209,6 @@ msgstr ""
 "Ağ türüne göre bölüm belirteci, vlan ağ türü için VLAN ID, geneve, gre ve "
 "vxlan ağ türleri için tünel ID"
 
-msgid "Select an availability zone for the server"
-msgstr "Sunucu için kullanılabilirlik bölgesi seçin"
-
 msgid "Server (name or ID)"
 msgstr "Sunucu (isim veya ID)"
 
@@ -5107,18 +4227,12 @@ msgstr "İmaj oluşturulacak sunucu (isi
 msgid "Server to list events (name or ID)"
 msgstr "Olayları listelenecek sunucu (isim veya ID)"
 
-msgid "Server to receive the IP address (name or ID)"
-msgstr "IP adresin alınacağı sunucu (isim veya ID)"
-
 msgid "Server to receive the fixed IP address (name or ID)"
 msgstr "Sabit IP adresleri alınacak sunucu (isim veya ID)"
 
 msgid "Server to receive the floating IP address (name or ID)"
 msgstr "Kayan IP adresi alınacak sunucu (isim veya ID)"
 
-msgid "Server to remove the IP address from (name or ID)"
-msgstr "IP adresin kaldırılacağı sunucu (isim veya ID)"
-
 msgid "Server to remove the fixed IP address from (name or ID)"
 msgstr "Sabit IP adresin silineceği sunucu (isim veya ID)"
 
@@ -5200,39 +4314,9 @@ msgstr "Gösterilecek servis (tür, isim
 msgid "Service to modify (type, name or ID)"
 msgstr "Düzenlenecek servis (tür, isim veya ID)"
 
-msgid ""
-"Service type for this subnet e.g.: network:floatingip_agent_gateway. Must be "
-"a valid device owner value for a network port (repeat option to set multiple "
-"service types)"
-msgstr ""
-"Bu alt ağ için servis türü örn: network:floatingip_agent_gateway. Bir ağ "
-"bağlantı noktası için geçerli bir cihaz sahibi değeri olmalıdır (birden "
-"fazla servis türü ayarlamak için seçeneği tekrarlayın)"
-
-msgid ""
-"Service type to be removed from this subnet e.g.: network:"
-"floatingip_agent_gateway. Must be a valid device owner value for a network "
-"port (repeat option to unset multiple service types)"
-msgstr ""
-"Bu altağdan kaldırılacak servis türü örn: network:floatingip_agent_gateway. "
-"Bir ağ bağlantı noktası için geçerli bir aygıt sahibi değeri olmalıdır "
-"(birden fazla servis türünün ayarını kaldırmak için seçeneği tekrarlayın)"
-
-msgid ""
-"Service type to which the flavor applies to: e.g. VPN (See openstack network "
-"service provider list for loaded examples.)"
-msgstr ""
-"Flavor'ın uygulanacağı hizmet türü: ör. VPN (Yüklü sunucular için açık devre "
-"ağ servis sağlayıcısı listesine bakın.)"
-
 msgid "Service(s) to delete (type, name or ID)"
 msgstr "Silinecek servis(ler) (tür, isim veya ID)"
 
-msgid "Set DNS name to this port (requires DNS integration extension)"
-msgstr ""
-"DNS adını bu bağlantı noktasına ayarlayın (DNS entegrasyon uzantısı "
-"gerektirir)"
-
 msgid "Set Network QoS rule properties"
 msgstr "Ağ QoS kural özelliklerini ayarla"
 
@@ -5353,9 +4437,6 @@ msgstr ""
 msgid "Set availability zone name"
 msgstr "Kullanılabilirlik bölge adını ayarla"
 
-msgid "Set compute agent properties"
-msgstr "Hesaplama ajanı özelliklerini ayarla"
-
 msgid "Set compute service properties"
 msgstr "Hesaplama servisi özelliklerini ayarla"
 
@@ -5371,24 +4452,9 @@ msgstr "Kap özelliklerini ayarla"
 msgid "Set credential properties"
 msgstr "Kimlik bilgileri özelliklerini ayarla"
 
-msgid ""
-"Set data plane status of this port (ACTIVE | DOWN). Unset it to None with "
-"the 'port unset' command (requires data plane status extension)"
-msgstr ""
-"Bu bağlantı noktasının veri düzlemi durumunu ayarlayın (ACTIVE | DOWN). "
-"'port unset' komutu ile None'a getirin (veri düzlemi durum uzantısı "
-"gerektirir)"
-
 msgid "Set default project (name or ID)"
 msgstr "Varsayılan projeyi ayarla (isim veya ID)"
 
-msgid ""
-"Set default quota for subnet pool as the number ofIP addresses allowed in a "
-"subnet"
-msgstr ""
-"Bir alt ağda izin verilen IP adreslerinin sayısı olarak alt ağ havuzu için "
-"varsayılan kota ayarla"
-
 msgid "Set domain properties"
 msgstr "Alan özelliklerini ayarla"
 
@@ -5416,9 +4482,6 @@ msgstr "Yüzen IP açıklaması ayarla"
 msgid "Set group properties"
 msgstr "Grup özelliklerini ayarla"
 
-msgid "Set host properties"
-msgstr "Sunucu özelliklerini ayarla"
-
 msgid "Set identity provider description"
 msgstr "Kimlik sağlayıcı tanımlarını ayarla"
 
@@ -5467,9 +4530,6 @@ msgstr "Ağ bölüm ismi ayarla"
 msgid "Set network segment properties"
 msgstr "Ağ kesimi özelliklerini ayarla"
 
-msgid "Set new root password (interactive only)"
-msgstr "Yeni root parolası ayarla (sadece interaktif)"
-
 msgid "Set object properties"
 msgstr "Nesne özelliklerini ayarla"
 
@@ -5491,18 +4551,12 @@ msgstr "Proje ismini ayarla"
 msgid "Set project properties"
 msgstr "Proje özelliklerini ayarla"
 
-msgid "Set quotas for <class>"
-msgstr "<class> için kotaları ayarla"
-
 msgid "Set quotas for a specific <volume-type>"
 msgstr "Belirli bir <volume-type> için kota ayarla"
 
 msgid "Set quotas for project or class"
 msgstr "Proje veya sınıf için kotaları ayarla"
 
-msgid "Set quotas for this project or class (name/ID)"
-msgstr "Bu proje veya sınıf için (isim/ID) kotaları ayarla"
-
 msgid "Set region properties"
 msgstr "Bölgenin özelliklerini ayarla"
 
@@ -5546,9 +4600,6 @@ msgstr "Servis özelliklerini ayarla"
 msgid "Set service provider properties"
 msgstr "Servis sağlayıcı özelliklerini ayarlayın"
 
-msgid "Set snapshot properties"
-msgstr "Anlık görüntü özelliklerini ayarlayın"
-
 msgid "Set subnet description"
 msgstr "Alt ağ açıklaması ayarla"
 
@@ -5581,32 +4632,6 @@ msgid "Set subnet properties"
 msgstr "Altağ özelliklerini ayarla"
 
 msgid ""
-"Set the class that provides encryption support for this volume type (e.g "
-"\"LuksEncryptor\") (admin only) (This option is required when setting "
-"encryption type of a volume for the first time. Consider using other "
-"encryption options such as: \"--encryption-cipher\", \"--encryption-key-size"
-"\" and \"--encryption-control-location\")"
-msgstr ""
-"Bu birim türü için şifreleme desteği sağlayan sınıfı ayarlayın (örn "
-"\"LuksEncryptor\") (sadece yönetici) (Bu seçenek, bir disk bölümü şifreleme "
-"türünü ilk kez ayarlarken gereklidir. Şu diğer şifreleme seçeneklerini "
-"kullanmayı düşünün: \"--encryption-cipher\", \"--encryption-key-size\" ve "
-"\"--encryption-control-location\")"
-
-msgid ""
-"Set the class that provides encryption support for this volume type (e.g "
-"\"LuksEncryptor\") (admin only) (This option is required when setting "
-"encryption type of a volume. Consider using other encryption options such "
-"as: \"--encryption-cipher\", \"--encryption-key-size\" and \"--encryption-"
-"control-location\")"
-msgstr ""
-"Bu disk bölümü türü için şifreleme desteği sağlayan sınıfı ayarla (örn "
-"\"LuksEncryptor\") (sadece yönetici) (Bir disk bölümünün şifreleme türü "
-"ayarlanırken bu seçenek zorunludur. \"--encryption-cipher\", \"--encryption-"
-"key-size\" ve \"--encryption-control-location\" gibi diğer şifreleme "
-"seçeneklerini kullanmayı göz önünde bulundurun)"
-
-msgid ""
 "Set the encryption algorithm or mode for this volume type (e.g \"aes-xts-"
 "plain64\") (admin only)"
 msgstr ""
@@ -5642,9 +4667,6 @@ msgstr ""
 "encryption-cipher\", \"--encryption-key-size\" ve \"--encryption-provider\" "
 "gibi diğer şifreleme seçeneklerini kullanmayı göz önünde bulundurun)"
 
-msgid "Set the password on the rebuilt instance"
-msgstr "Yeniden oluşturulmuş sunucudaki parolayı ayarla"
-
 msgid "Set the router as highly available (disabled router only)"
 msgstr ""
 "Yönlendiriciyi yüksek kullanılabilirlikli olarak ayarla (sadece "
@@ -5672,17 +4694,6 @@ msgstr "Bunu varsayılan olmayan bir ağ
 msgid "Set this as a non-default subnet pool"
 msgstr "Bunu varsayılan olmayan altağ havuzu olarak ayarla"
 
-msgid ""
-"Set this network as an external network (external-net extension required)"
-msgstr ""
-"Bu şebekeyi harici bir ağ olarak ayarlayın (harici ağ uzantısı gerekir)"
-
-msgid "Set this network as an internal network"
-msgstr "Bu şebekeyi dahili bir şebeke olarak ayarlayın"
-
-msgid "Set this network as an internal network (default)"
-msgstr "Bu ağı dahili bir ağ olarak ayarlayın (varsayılan)"
-
 msgid "Set this subnet pool as not shared"
 msgstr "Bu alt ağ havuzunu paylaşılmayan olarak ayarlayın"
 
@@ -5754,9 +4765,6 @@ msgstr "Projeler arasında adres kapsam
 msgid "Share the network between projects"
 msgstr "Ağları projeler arasında paylaşın"
 
-msgid "Shelve server(s)"
-msgstr "Sunucu(yu/ları) raftan çıkart"
-
 msgid "Show API extension"
 msgstr "API uzantısını göster"
 
@@ -5804,12 +4812,6 @@ msgstr ""
 "Tüm projeler için detayları göster. Sadece yönetici. (varsayılan olarak "
 "False)"
 
-msgid ""
-"Show limits for a specific project (name or ID) [only valid with --absolute]"
-msgstr ""
-"Belirli bir proje için sınırları göster (isim veya ID) [sadece --absolute "
-"ile geçerli]"
-
 msgid "Show network IP availability details"
 msgstr "Ağ IP kullanılabilirlik detaylarını göster"
 
@@ -5832,30 +4834,12 @@ msgstr "Parolaları düz metin olarak g
 msgid "Show project's subtree (children) as a list"
 msgstr "Projenin alt projelerini (çocuklarını) bir liste olarak göster"
 
-msgid "Show quotas for <class>"
-msgstr "<class> için kotaları göster"
-
-msgid "Show quotas for project or class"
-msgstr "Proje veya sınıf için kotaları göster"
-
-msgid "Show quotas for this project or class (name or ID)"
-msgstr "Bu proje veya sınıf (isim veaya ID) için kotaları göster"
-
-msgid "Show rate limits"
-msgstr "Oran sınırları göster"
-
 msgid "Show resource usage for a single project"
 msgstr "Tek bir proje için kaynak kullanımını göster"
 
 msgid "Show serial console URL"
 msgstr "serial konsol URL'ini göster"
 
-msgid "Show server details"
-msgstr "Sunucu detaylarını göster"
-
-msgid "Show server event details"
-msgstr "Sunucu olay detaylarını listele"
-
 msgid "Show server's console output"
 msgstr "Sunucunun konsol çıktısını göster"
 
@@ -5868,9 +4852,6 @@ msgstr "Servis katalog bilgisini göster
 msgid "Show the project's parents as a list"
 msgstr "Projenin üst projelerini bir liste olarak göster"
 
-msgid "Show volume details"
-msgstr "Disk bölümü detaylarını göster"
-
 msgid "Show volume transfer request details."
 msgstr "Disk bölümü aktarım isteği detaylarını göster."
 
@@ -5880,9 +4861,6 @@ msgstr "xvpvnc konsol URL'ini göster"
 msgid "Size of image data (in bytes)"
 msgstr "İmaj verisinin boyutu (bayt cinsinden)"
 
-msgid "Skip flavor and image name lookup."
-msgstr "Flavor veya imaj ismi aramasını atla."
-
 msgid "Snapshot to backup (name or ID)"
 msgstr "Yedeği alınacak anlık görüntü (isim veya ID)"
 
@@ -5911,40 +4889,10 @@ msgstr ""
 "(varsayılan: ad:artan), virgülle ayrılmış olarak birden çok anahtar ve yön "
 "belirlenebilir"
 
-msgid "Specific service endpoint to use"
-msgstr "Kullanılacak belirli bir servis uç noktası"
-
 msgid "Specifies if the role grant is inheritable to the sub projects"
 msgstr ""
 "Rol atamasının alt projelere miras bırakılıp bırakılmayacağını belirler"
 
-msgid ""
-"Specify a gateway for the subnet.  The three options are: <ip-address>: "
-"Specific IP address to use as the gateway, 'auto': Gateway address should "
-"automatically be chosen from within the subnet itself, 'none': This subnet "
-"will not use a gateway, e.g.: --gateway 192.168.9.1, --gateway auto, --"
-"gateway none (default is 'auto')."
-msgstr ""
-"Alt ağ için bir geçit belirle.  Üç seçenek: <ip-address>: geçit olarak "
-"kullanılacak belirli bir IP adresi, 'auto': Geçit adresi ağdan otomatik "
-"olarak seçilmelidir, 'none': Bu alt ağ bir geçit kullanmayacak, örn: --"
-"gateway 192.168.9.1, --gateway auto, --gateway none (varsayılan 'auto')."
-
-msgid ""
-"Specify a gateway for the subnet. The options are: <ip-address>: Specific IP "
-"address to use as the gateway, 'none': This subnet will not use a gateway, e."
-"g.: --gateway 192.168.9.1, --gateway none."
-msgstr ""
-"Alt ağ için bir geçit belirle. Seçenekler: <ip-address>: Geçit olarak "
-"kullanılacak belirli bir IP adresi, 'none': Bu alt ağ geçit olarak "
-"kullanılmayacak, örn: --gateway 192.168.9.1, --gateway none."
-
-msgid "Specify an alternate project (name or ID)"
-msgstr "Alternatif bir proje belirle (isim veya ID)"
-
-msgid "Specify an alternate user (name or ID)"
-msgstr "Alternatif bir kullanıcı belirle (isim veya ID)"
-
 msgid "Specify if this network should be used as the default external network"
 msgstr ""
 "Bu ağın varsayılan dış ağ olarak kullanılması gerekip gerekmediğini "
@@ -5957,19 +4905,6 @@ msgstr ""
 "auto veya none --nic'i belirtmek başka bir --nic, --network veya --port "
 "değeriyle kullanılamaz."
 
-msgid ""
-"Specifying the auth-key as a positional argument has been deprecated.  "
-"Please use the --auth-key option in the future."
-msgstr ""
-"Yetki anahtarını pozisyonel argüman olarak belirleme kullanımdan "
-"kaldırıldı.  Lütfen gelecekte --auth-key seçeneğini kullanın."
-
-msgid "Start server(s)."
-msgstr "Sunucu(ları/yu) başlat."
-
-msgid "Stop server(s)."
-msgstr "Sunucu(ları/yu) durdur."
-
 #, python-format
 msgid "Subnet does not contain %(option)s %(value)s"
 msgstr "Ağ %(option)s %(value)s'yü içermiyor"
@@ -5977,10 +4912,6 @@ msgstr "Ağ %(option)s %(value)s'yü iç
 msgid "Subnet on which you want to create the floating IP (name or ID)"
 msgstr "Yüzen IP'yi oluşturmak istediğiniz alt ağ (isim veya ID)"
 
-#, python-format
-msgid "Subnet pool does not contain prefix %s"
-msgstr "%s önekini içermeyen altağ havuzu"
-
 msgid "Subnet pool from which this subnet will obtain a CIDR (Name or ID)"
 msgstr "Bu alt ağın bir CIDR alacağı alt ağ havuzu (isim veya ID)"
 
@@ -6024,242 +4955,27 @@ msgstr ""
 "%s'e eklenecek etiketler (birden fazla etiket ayarlamak için seçeneği tekrar "
 "et)"
 
-#, python-format
-msgid "Tag to be removed from the %s (repeat option to remove multiple tags)"
-msgstr ""
-"%s'den kaldırılacak etiket (birden fazla etiket silmek için seçenekleri "
-"tekrarlayın)"
-
-msgid "Target hostname"
-msgstr "Hedef sunucu adı"
-
 msgid "Thaw and enable the specified volume host"
 msgstr "Belirtilen disk bölümü barındırıcısını çöz ve etkinleştir"
 
-#, python-format
-msgid "The %(old)s option is deprecated, please use %(new)s instead."
-msgstr ""
-"%(old)s seçeneği kullanımdan kaldırıldı, lütfen onun yerine %(new)s kullanın."
-
-msgid "The --clear-routes option is deprecated, please use --no-route instead."
-msgstr ""
-"--clear-routes seçeneği kullanımdan kaldırıldı, onun yerine --no-route "
-"kullanın."
-
-msgid "The --device-id option is deprecated, please use --device instead."
-msgstr ""
-"--device-id seçeneği kullanımdan kaldırıldı, lütfen onun yerine --device "
-"komutunu kullanın."
-
-msgid "The --host-id option is deprecated, please use --host instead."
-msgstr ""
-"--host-id seçeneği kullanımdan kaldırıldı, lütfen onun yerine --host "
-"komutunu kullanın."
-
-msgid "The --owner option is deprecated, please use --project instead."
-msgstr ""
-"--owner seçeneği kullanımdan kaldırıldı, onun yerine lütfen --project "
-"seçeneğini kullanın."
-
 msgid ""
 "The ID of the volume backend replication target where the host will failover "
 "to (required)"
 msgstr ""
 "Ana bilgisayarın üstleneceği disk bölümü arkaplan kopyası ID'si (zorunlu)"
 
-msgid ""
-"The argument --type is deprecated, use service create --name <service-name> "
-"type instead."
-msgstr ""
-"--type argümanı kullanımdan kaldırılmıştır, onun yerine service create --"
-"name <service-name> type komutunu kullanın."
-
-msgid ""
-"The attribute(s) of the exsiting remote volume snapshot (admin required) "
-"(repeat option to specify multiple attributes) e.g.: '--remote-source source-"
-"name=test_name --remote-source source-id=test_id'"
-msgstr ""
-"Varolan uzak birimin anlık görüntüsünün nitelikleri (yönetici gerekli) "
-"(birden fazla özellik belirlemek için seçeneği tekrarlayın) örn: '--remote-"
-"source source-name=test_name --remote-source source-id=test_id'"
-
-msgid "The last backup of the previous page (name or ID)"
-msgstr "Bir önceki sayfanın son yedeği (isim veya ID)"
-
-msgid "The last flavor ID of the previous page"
-msgstr "Bir önceki sayfanın son flavor ID'si"
-
-msgid ""
-"The last image of the previous page. Display list of images after marker. "
-"Display all images if not specified. (name or ID)"
-msgstr ""
-"Bir önceki sayfanın son imajı. İşaretçiden sonraki imajların listesini "
-"görüntüle. Belirtilmemişse tüm imajları görüntüleyin. (isim veya ID)"
-
-msgid ""
-"The last server of the previous page. Display list of servers after marker. "
-"Display all servers if not specified. (name or ID)"
-msgstr ""
-"Bir önceki sayfanın son sunucusu. İşaretçi sonrasındaki sunucuların "
-"listesini görüntüle. Belirtilmemişse tüm sunucuları görüntüleyin. (isim veya "
-"ID)"
-
-msgid "The last snapshot ID of the previous page"
-msgstr "Bir önceki sayfanın son anlık görüntü ID'si"
-
-msgid "The last volume ID of the previous page"
-msgstr "Bir önceki sayfanın son disk bölümü ID'si"
-
 msgid "The object to which this RBAC policy affects (name or ID)"
 msgstr "Bu RBAC politikasının etkilediği nesne (ad veya kimlik)"
 
 msgid "The owner project (name or ID)"
 msgstr "Projenin sahibi (isim veya ID)"
 
-msgid ""
-"The physical mechanism by which the virtual network is implemented. For "
-"example: flat, geneve, gre, local, vlan, vxlan."
-msgstr ""
-"Sanal ağın uygulandığı fiziksel mekanizma. Örneğin: düz, geneve, gre, yerel, "
-"vlan, vxlan."
-
 msgid "The project to which the RBAC policy will be enforced (name or ID)"
 msgstr "RBAC politikası dayatılacak proje (isim veya ID)"
 
 msgid "The remote IP prefix to associate with this rule"
 msgstr "Bu kural ile ilişkilendirilecek uzak IP ön eki"
 
-msgid ""
-"This command has been deprecated. Please use \"floating ip create\" instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"floating ip create\" "
-"kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"floating ip delete\" instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen yerine \"floating ip delete\" "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"floating ip list\" instead."
-msgstr ""
-"Bu komut kullanımdan kalktı. Onun yerine lütfen \"floating ip list\" "
-"kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"floating ip pool list\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen, onun yerine \"floating ip pool list"
-"\" komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"floating ip show\" instead."
-msgstr ""
-"Bu komut önerilmiyor. Lütfen bunun yerine \"floating ip show\"ı kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"server add fixed ip\" instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Onun yerine lütfen \"server add fixed ip\" "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"server add floating ip\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırılmıştır. Onun yerine lütfen \"server add "
-"floating ip\" kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"server remove fixed ip\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"server remove fixed ip"
-"\" komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"server remove floating ip\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Onun yerine lütfen \"server remove floating "
-"ip\" komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume backup create\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Onun yerine lütfen \"volume backup create\" "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume backup delete\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume backup delete\" "
-"kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume backup list\" instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume backup list\"  "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume backup restore\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume backup restore"
-"\" komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume backup show\" instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume backup show\" "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume snapshot create\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume snapshot create"
-"\" komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume snapshot delete\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume snapshot delete"
-"\" komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume snapshot list\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Onun yerine lütfen \"volume snapshot list\" "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume snapshot set\" instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen bunun yerine \"volume snapshot set\" "
-"komutunu kullanın."
-
-msgid ""
-"This command has been deprecated. Please use \"volume snapshot show\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume snapshot show\" "
-"komutunu kullan."
-
-msgid ""
-"This command has been deprecated. Please use \"volume snapshot unset\" "
-"instead."
-msgstr ""
-"Bu komut kullanımdan kaldırıldı. Lütfen onun yerine \"volume snapshot unset"
-"\" komutunu kullanın."
-
 msgid "Token to be deleted"
 msgstr "Silinecek jeton"
 
@@ -6283,20 +4999,12 @@ msgstr "Mimari türü"
 msgid "Type of hypervisor"
 msgstr "Arakatman türü"
 
-msgid ""
-"Type of the object that RBAC policy affects (\"qos_policy\" or \"network\")"
-msgstr ""
-"RBAC politikasını etkileyen nesne türü (\"qos_policy\" veya \"network\")"
-
 msgid "URL"
 msgstr "URL"
 
 msgid "URL of the agent"
 msgstr "Ajanın URL'i"
 
-msgid "Unique flavor ID; 'auto' creates a UUID (default: auto)"
-msgstr "Benzersiz flavor ID'si; 'auto'  bir UUID oluşturur (varsayılan: auto)"
-
 msgid "Unlock server(s)"
 msgstr "Sunucu(ların/nun) kilidini kaldır"
 
@@ -6344,12 +5052,6 @@ msgstr "Proje özelliklerini kaldır"
 msgid "Unset router properties"
 msgstr "Yönlendirici özelliklerini kaldır"
 
-msgid "Unset server properties"
-msgstr "Sunucu özelliklerini kaldır"
-
-msgid "Unset snapshot properties"
-msgstr "Anlık görüntü özelliklerinin ayarını kaldır"
-
 msgid "Unset subnet pool properties"
 msgstr "Altağ havuz özelliklerinin ayarlarını kaldır"
 
@@ -6433,12 +5135,6 @@ msgid "Use public IP address"
 msgstr "Genel IP adresi kullan"
 
 msgid ""
-"Use specified volume as the config drive, or 'True' to use an ephemeral drive"
-msgstr ""
-"Belirtilen birimi yapılandırma sürücüsü olarak kullanın veya kısa ömürlü bir "
-"sürücüyü kullanmak için 'True' kullanın"
-
-msgid ""
 "Used to populate the backup_type property of the backup image (default: "
 "empty)"
 msgstr ""
@@ -6451,9 +5147,6 @@ msgstr "Üst veri sunucusundan sunmak i
 msgid "User description"
 msgstr "Kullanıcı tanımı"
 
-msgid "User must be specified"
-msgstr "Kullanıcı belirtilmeli"
-
 msgid "User that is assuming authorization (name or ID)"
 msgstr "Yetki varsayan kullanıcı (adı veya kimliği)"
 
@@ -6472,9 +5165,6 @@ msgstr "Gösterilecek kullanıcı (isim
 msgid "User to filter (name or ID)"
 msgstr "Filtrelenecek kullanıcı (isim veya ID)"
 
-msgid "User to list (name or ID)"
-msgstr "Listelenecek kullanıcı (isim veya ID)"
-
 msgid "User to modify (name or ID)"
 msgstr "Düzenlenecek kullanıcı (isim veya ID)"
 
@@ -6498,13 +5188,6 @@ msgid "VLAN ID for VLAN networks or Tunn
 msgstr "VLAN ağları için VLAN ID veya GENEVA/GRE/VXLAN ağları için Tünel ID"
 
 msgid ""
-"VNIC type for this port (direct | direct-physical | macvtap | normal | "
-"baremetal | virtio-forwarder,  default: normal)"
-msgstr ""
-"Bu bağlantı noktası için VNIC türü (direct | direct-physical | macvtap | "
-"normal | baremetal | virtio-forwarder, varsayılan: normal)"
-
-msgid ""
 "Validate the requirements for auto allocated topology. Does not return a "
 "topology."
 msgstr ""
@@ -6536,25 +5219,6 @@ msgstr ""
 msgid "Volume name"
 msgstr "Disk bölümü ismi"
 
-msgid ""
-"Volume or snapshot (name or ID) must be specified if --block-device-mapping "
-"is specified"
-msgstr ""
-"Disk bölümü veya anlık görüntü (isim veya ID), eğer --block-device-mapping "
-"belirtildiyse, belirtilmek zorundadır."
-
-msgid "Volume size in GB (Required unless --snapshot or --source is specified)"
-msgstr ""
-"GB cinsinden disk bölümü boyutu (--snapshot veya --source belirtilmezse "
-"gereklidir)"
-
-msgid ""
-"Volume size in GB (Required unless --snapshot or --source or --source-"
-"replicated is specified)"
-msgstr ""
-"GB cinsinden disk bölümü boyutu (--snapshot veya --source veya --source-"
-"replicated belirtilmedikçe gereklidir)"
-
 msgid "Volume to add (name or ID)"
 msgstr "Eklenecek disk bölümü (isim veya ID)"
 
@@ -6576,12 +5240,6 @@ msgstr "Düzenlenecek disk bölümü (is
 msgid "Volume to remove (name or ID)"
 msgstr "Kaldırılacak disk bölümü (isim veya ID)"
 
-msgid "Volume to restore to (name or ID)"
-msgstr "Geri yüklenecek disk bölümü (isim veya ID)"
-
-msgid "Volume to snapshot (name or ID)"
-msgstr "Anlık görüntüsü oluşturulacak disk bölümü (isim veya ID)"
-
 msgid "Volume to snapshot (name or ID) (default is <snapshot-name>)"
 msgstr ""
 "Anlık görüntüsü alınacak disk bölümü (isim veya ID) (varsayılan <snapshot-"
@@ -6673,25 +5331,6 @@ msgstr "Yeniden yapılandırmanın tamam
 msgid "Wait for resize to complete"
 msgstr "Yeniden boyutlandırmanın tamamlanmasını bekleyin"
 
-msgid ""
-"You must specify '--external-gateway' in orderto update the SNAT or fixed-ip "
-"values"
-msgstr ""
-"SNAT veya sabit ip değerlerini güncellemek için '--external-gateway' "
-"belirtmelisiniz"
-
-msgid "argument --auth-key is required"
-msgstr "--auth-key argümanı zorunludur"
-
-msgid ""
-"can't create server with port specified since network endpoint not enabled"
-msgstr ""
-"ağ uç noktası etkin olmadığı için belirtilen bağlantı noktası ile sunucu "
-"oluşturulamadı"
-
-msgid "either network or port should be specified but not both"
-msgstr "ya ağ ya da bağlantı noktası belirtilmelidir ama ikisi bir arada değil"
-
 msgid "many found"
 msgstr "çok bulundu"
 
diff -pruN 7.4.0-3/openstackclient/network/client.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/client.py
--- 7.4.0-3/openstackclient/network/client.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/client.py	2025-07-07 22:41:56.000000000 +0000
@@ -9,7 +9,6 @@
 #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #   License for the specific language governing permissions and limitations
 #   under the License.
-#
 
 import logging
 
@@ -17,26 +16,17 @@ from osc_lib import utils
 
 from openstackclient.i18n import _
 
-
 LOG = logging.getLogger(__name__)
 
+# global variables used when building the shell
 DEFAULT_API_VERSION = '2.0'
 API_VERSION_OPTION = 'os_network_api_version'
-API_NAME = "network"
-API_VERSIONS = {
-    "2.0": "openstack.connection.Connection",
-    "2": "openstack.connection.Connection",
-}
+API_NAME = 'network'
+API_VERSIONS = ('2.0', '2')
 
 
 def make_client(instance):
     """Returns a network proxy"""
-    # NOTE(dtroyer): As of osc-lib 1.8.0 and OpenStackSDK 0.10.0 the
-    #                old Profile interface and separate client creation
-    #                for each API that uses the SDK is unnecessary.  This
-    #                callback remains as a remnant of the original plugin
-    #                interface and to avoid the code churn of changing all
-    #                of the existing references.
     LOG.debug(
         'Network client initialized using OpenStack SDK: %s',
         instance.sdk_connection.network,
@@ -50,9 +40,7 @@ def build_option_parser(parser):
         '--os-network-api-version',
         metavar='<network-api-version>',
         default=utils.env('OS_NETWORK_API_VERSION'),
-        help=_(
-            "Network API version, default=%s " "(Env: OS_NETWORK_API_VERSION)"
-        )
+        help=_("Network API version, default=%s (Env: OS_NETWORK_API_VERSION)")
         % DEFAULT_API_VERSION,
     )
     return parser
diff -pruN 7.4.0-3/openstackclient/network/common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/common.py
--- 7.4.0-3/openstackclient/network/common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/common.py	2025-07-07 22:41:56.000000000 +0000
@@ -12,9 +12,12 @@
 #
 
 import abc
+import argparse
 import contextlib
 import logging
+import typing as ty
 
+import cliff.app
 import openstack.exceptions
 from osc_lib.cli import parseractions
 from osc_lib.command import command
@@ -65,6 +68,8 @@ class NetDetectionMixin(metaclass=abc.AB
     present the options for both network types, often qualified accordingly.
     """
 
+    app: cliff.app.App
+
     @property
     def _network_type(self):
         """Discover whether the running cloud is using neutron or nova-network.
@@ -131,9 +136,9 @@ class NetDetectionMixin(metaclass=abc.AB
             )
         )
 
-    def get_parser(self, prog_name):
+    def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
         LOG.debug('get_parser(%s)', prog_name)
-        parser = super().get_parser(prog_name)
+        parser = super().get_parser(prog_name)  # type: ignore
         parser = self.update_parser_common(parser)
         LOG.debug('common parser: %s', parser)
         if self.is_neutron or self.is_docs_build:
@@ -162,7 +167,7 @@ class NetDetectionMixin(metaclass=abc.AB
             )
         elif self.is_nova_network:
             return self.take_action_compute(
-                self.app.client_manager.sdk_connection.compute, parsed_args
+                self.app.client_manager.compute, parsed_args
             )
 
     def take_action_network(self, client, parsed_args):
@@ -211,7 +216,7 @@ class NetworkAndComputeDelete(NetworkAnd
                     )
                 else:
                     self.take_action_compute(
-                        self.app.client_manager.sdk_connection.compute,
+                        self.app.client_manager.compute,
                         parsed_args,
                     )
             except Exception as e:
@@ -269,7 +274,7 @@ class NetworkAndComputeShowOne(
                 )
             else:
                 return self.take_action_compute(
-                    self.app.client_manager.sdk_connection.compute, parsed_args
+                    self.app.client_manager.compute, parsed_args
                 )
         except openstack.exceptions.HttpException as exc:
             msg = _("Error while executing command: %s") % exc.message
@@ -295,16 +300,15 @@ class NeutronCommandWithExtraArgs(comman
     }
 
     def _get_property_converter(self, _property):
-        if 'type' not in _property:
-            converter = str
-        else:
+        if 'type' in _property:
             converter = self._allowed_types_dict.get(_property['type'])
+        else:
+            converter = str
 
         if not converter:
             raise exceptions.CommandError(
                 _(
-                    "Type {property_type} of property {name} "
-                    "is not supported"
+                    "Type {property_type} of property {name} is not supported"
                 ).format(
                     property_type=_property['type'], name=_property['name']
                 )
@@ -312,7 +316,7 @@ class NeutronCommandWithExtraArgs(comman
         return converter
 
     def _parse_extra_properties(self, extra_properties):
-        result = {}
+        result: dict[str, ty.Any] = {}
         if extra_properties:
             for _property in extra_properties:
                 converter = self._get_property_converter(_property)
@@ -345,7 +349,7 @@ class NeutronCommandWithExtraArgs(comman
 
 class NeutronUnsetCommandWithExtraArgs(NeutronCommandWithExtraArgs):
     def _parse_extra_properties(self, extra_properties):
-        result = {}
+        result: dict[str, ty.Any] = {}
         if extra_properties:
             for _property in extra_properties:
                 result[_property['name']] = None
diff -pruN 7.4.0-3/openstackclient/network/utils.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/utils.py
--- 7.4.0-3/openstackclient/network/utils.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/utils.py	2025-07-07 22:41:56.000000000 +0000
@@ -23,7 +23,7 @@ def transform_compute_security_group_rul
     from_port = info.pop('from_port')
     to_port = info.pop('to_port')
     if isinstance(from_port, int) and isinstance(to_port, int):
-        port_range = {'port_range': "%u:%u" % (from_port, to_port)}
+        port_range = {'port_range': f"{from_port}:{to_port}"}
     elif from_port is None and to_port is None:
         port_range = {'port_range': ""}
     else:
@@ -58,12 +58,12 @@ def str2list(strlist):
     return result
 
 
-def str2dict(strdict):
+def str2dict(strdict: str) -> dict[str, str]:
     """Convert key1:value1;key2:value2;... string into dictionary.
 
     :param strdict: string in the form of key1:value1;key2:value2
     """
-    result = {}
+    result: dict[str, str] = {}
     if not strdict:
         return result
     i = 0
diff -pruN 7.4.0-3/openstackclient/network/v2/address_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/address_group.py
--- 7.4.0-3/openstackclient/network/v2/address_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/address_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,10 +28,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -76,8 +75,7 @@ class CreateAddressGroup(command.ShowOne
             action='append',
             default=[],
             help=_(
-                "IP address or CIDR "
-                "(repeat option to set multiple addresses)"
+                "IP address or CIDR (repeat option to set multiple addresses)"
             ),
         )
         parser.add_argument(
@@ -139,7 +137,7 @@ class DeleteAddressGroup(command.Command
         if result > 0:
             total = len(parsed_args.address_group)
             msg = _(
-                "%(result)s of %(total)s address groups failed " "to delete."
+                "%(result)s of %(total)s address groups failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -159,8 +157,7 @@ class ListAddressGroup(command.Lister):
             '--project',
             metavar="<project>",
             help=_(
-                "List address groups according to their project "
-                "(name or ID)"
+                "List address groups according to their project (name or ID)"
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
@@ -233,8 +230,7 @@ class SetAddressGroup(common.NeutronComm
             action='append',
             default=[],
             help=_(
-                "IP address or CIDR "
-                "(repeat option to set multiple addresses)"
+                "IP address or CIDR (repeat option to set multiple addresses)"
             ),
         )
         return parser
diff -pruN 7.4.0-3/openstackclient/network/v2/address_scope.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/address_scope.py
--- 7.4.0-3/openstackclient/network/v2/address_scope.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/address_scope.py	2025-07-07 22:41:56.000000000 +0000
@@ -144,7 +144,7 @@ class DeleteAddressScope(command.Command
         if result > 0:
             total = len(parsed_args.address_scope)
             msg = _(
-                "%(result)s of %(total)s address scopes failed " "to delete."
+                "%(result)s of %(total)s address scopes failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -176,8 +176,7 @@ class ListAddressScope(command.Lister):
             '--project',
             metavar="<project>",
             help=_(
-                "List address scopes according to their project "
-                "(name or ID)"
+                "List address scopes according to their project (name or ID)"
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
diff -pruN 7.4.0-3/openstackclient/network/v2/default_security_group_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/default_security_group_rule.py
--- 7.4.0-3/openstackclient/network/v2/default_security_group_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/default_security_group_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,10 +28,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'name', 'revision_number']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
diff -pruN 7.4.0-3/openstackclient/network/v2/floating_ip.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/floating_ip.py
--- 7.4.0-3/openstackclient/network/v2/floating_ip.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/floating_ip.py	2025-07-07 22:41:56.000000000 +0000
@@ -13,6 +13,7 @@
 """IP Floating action implementations"""
 
 from openstack import exceptions as sdk_exceptions
+from osc_lib.cli import format_columns
 from osc_lib import utils
 from osc_lib.utils import tags as _tag
 
@@ -22,15 +23,14 @@ from openstackclient.identity import com
 from openstackclient.network import common
 
 _formatters = {
-    'port_details': utils.format_dict,
+    'port_details': format_columns.DictColumn,
 }
 
 
 def _get_network_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -123,7 +123,7 @@ class CreateFloatingIP(
             '--port',
             metavar='<port>',
             help=self.enhance_help_neutron(
-                _("Port to be associated with the floating IP " "(name or ID)")
+                _("Port to be associated with the floating IP (name or ID)")
             ),
         )
         parser.add_argument(
@@ -243,18 +243,26 @@ class ListFloatingIP(common.NetworkAndCo
         parser.add_argument(
             '--network',
             metavar='<network>',
+            dest='networks',
+            action='append',
             help=self.enhance_help_neutron(
                 _(
-                    "List floating IP(s) according to "
-                    "given network (name or ID)"
+                    "List floating IP(s) according to given network "
+                    "(name or ID) "
+                    "(repeat option to fiter on multiple networks)"
                 )
             ),
         )
         parser.add_argument(
             '--port',
             metavar='<port>',
+            dest='ports',
+            action='append',
             help=self.enhance_help_neutron(
-                _("List floating IP(s) according to given port (name or ID)")
+                _(
+                    "List floating IP(s) according to given port (name or ID) "
+                    "(repeat option to fiter on multiple ports)"
+                )
             ),
         )
         parser.add_argument(
@@ -268,18 +276,7 @@ class ListFloatingIP(common.NetworkAndCo
             '--floating-ip-address',
             metavar='<ip-address>',
             help=self.enhance_help_neutron(
-                _(
-                    "List floating IP(s) according to given floating IP "
-                    "address"
-                )
-            ),
-        )
-        parser.add_argument(
-            '--long',
-            action='store_true',
-            default=False,
-            help=self.enhance_help_neutron(
-                _("List additional fields in output")
+                _("List floating IP(s) according to given floating IP address")
             ),
         )
         parser.add_argument(
@@ -298,8 +295,8 @@ class ListFloatingIP(common.NetworkAndCo
             metavar='<project>',
             help=self.enhance_help_neutron(
                 _(
-                    "List floating IP(s) according to given project (name or "
-                    "ID)"
+                    "List floating IP(s) according to given project "
+                    "(name or ID) "
                 )
             ),
         )
@@ -307,16 +304,27 @@ class ListFloatingIP(common.NetworkAndCo
         parser.add_argument(
             '--router',
             metavar='<router>',
+            dest='routers',
+            action='append',
             help=self.enhance_help_neutron(
                 _(
-                    "List floating IP(s) according to given router (name or "
-                    "ID)"
+                    "List floating IP(s) according to given router "
+                    "(name or ID) "
+                    "(repeat option to fiter on multiple routers)"
                 )
             ),
         )
         _tag.add_tag_filtering_option_to_parser(
             parser, _('floating IP'), enhance_help=self.enhance_help_neutron
         )
+        parser.add_argument(
+            '--long',
+            action='store_true',
+            default=False,
+            help=self.enhance_help_neutron(
+                _("List additional fields in output")
+            ),
+        )
 
         return parser
 
@@ -324,7 +332,7 @@ class ListFloatingIP(common.NetworkAndCo
         network_client = self.app.client_manager.network
         identity_client = self.app.client_manager.identity
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'floating_ip_address',
             'fixed_ip_address',
@@ -332,7 +340,7 @@ class ListFloatingIP(common.NetworkAndCo
             'floating_network_id',
             'project_id',
         )
-        headers = (
+        headers: tuple[str, ...] = (
             'ID',
             'Floating IP Address',
             'Fixed IP Address',
@@ -341,7 +349,7 @@ class ListFloatingIP(common.NetworkAndCo
             'Project',
         )
         if parsed_args.long:
-            columns = columns + (
+            columns += (
                 'router_id',
                 'status',
                 'description',
@@ -349,7 +357,7 @@ class ListFloatingIP(common.NetworkAndCo
                 'dns_name',
                 'dns_domain',
             )
-            headers = headers + (
+            headers += (
                 'Router',
                 'Status',
                 'Description',
@@ -360,22 +368,33 @@ class ListFloatingIP(common.NetworkAndCo
 
         query = {}
 
-        if parsed_args.network is not None:
-            network = network_client.find_network(
-                parsed_args.network, ignore_missing=False
-            )
-            query['floating_network_id'] = network.id
-        if parsed_args.port is not None:
-            port = network_client.find_port(
-                parsed_args.port, ignore_missing=False
-            )
-            query['port_id'] = port.id
+        if parsed_args.networks is not None:
+            network_ids = []
+            for network in parsed_args.networks:
+                network_id = network_client.find_network(
+                    network, ignore_missing=False
+                ).id
+                network_ids.append(network_id)
+            query['floating_network_id'] = network_ids
+
+        if parsed_args.ports is not None:
+            port_ids = []
+            for port in parsed_args.ports:
+                port_id = network_client.find_port(
+                    port, ignore_missing=False
+                ).id
+                port_ids.append(port_id)
+            query['port_id'] = port_ids
+
         if parsed_args.fixed_ip_address is not None:
             query['fixed_ip_address'] = parsed_args.fixed_ip_address
+
         if parsed_args.floating_ip_address is not None:
             query['floating_ip_address'] = parsed_args.floating_ip_address
+
         if parsed_args.status:
             query['status'] = parsed_args.status
+
         if parsed_args.project is not None:
             project = identity_common.find_project(
                 identity_client,
@@ -383,11 +402,15 @@ class ListFloatingIP(common.NetworkAndCo
                 parsed_args.project_domain,
             )
             query['project_id'] = project.id
-        if parsed_args.router is not None:
-            router = network_client.find_router(
-                parsed_args.router, ignore_missing=False
-            )
-            query['router_id'] = router.id
+
+        if parsed_args.routers is not None:
+            router_ids = []
+            for router in parsed_args.routers:
+                router_id = network_client.find_router(
+                    router, ignore_missing=False
+                ).id
+                router_ids.append(router_id)
+            query['router_id'] = router_ids
 
         _tag.get_tag_filtering_args(parsed_args, query)
 
@@ -409,14 +432,14 @@ class ListFloatingIP(common.NetworkAndCo
         )
 
     def take_action_compute(self, client, parsed_args):
-        columns = (
+        columns: tuple[str, ...] = (
             'ID',
             'IP',
             'Fixed IP',
             'Instance ID',
             'Pool',
         )
-        headers = (
+        headers: tuple[str, ...] = (
             'ID',
             'Floating IP Address',
             'Fixed IP Address',
@@ -458,8 +481,7 @@ class SetFloatingIP(common.NeutronComman
             metavar='<ip-address>',
             dest='fixed_ip_address',
             help=_(
-                "Fixed IP of the port "
-                "(required only if port has multiple IPs)"
+                "Fixed IP of the port (required only if port has multiple IPs)"
             ),
         )
         parser.add_argument(
@@ -578,7 +600,7 @@ class UnsetFloatingIP(common.NeutronComm
             parsed_args.floating_ip,
             ignore_missing=False,
         )
-        attrs = {}
+        attrs: dict[str, None] = {}
         if parsed_args.port:
             attrs['port_id'] = None
         if parsed_args.qos_policy:
diff -pruN 7.4.0-3/openstackclient/network/v2/floating_ip_port_forwarding.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/floating_ip_port_forwarding.py
--- 7.4.0-3/openstackclient/network/v2/floating_ip_port_forwarding.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/floating_ip_port_forwarding.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,6 +14,7 @@
 """Floating IP Port Forwarding action implementations"""
 
 import logging
+import typing as ty
 
 from osc_lib.command import command
 from osc_lib import exceptions
@@ -85,10 +86,9 @@ def validate_port(port):
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -149,7 +149,7 @@ class CreateFloatingIPPortForwarding(
             '--description',
             metavar='<description>',
             help=_(
-                "A text to describe/contextualize the use of the "
+                "Text to describe/contextualize the use of the "
                 "port forwarding configuration"
             ),
         )
@@ -165,7 +165,7 @@ class CreateFloatingIPPortForwarding(
         return parser
 
     def take_action(self, parsed_args):
-        attrs = {}
+        attrs: dict[str, ty.Any] = {}
         client = self.app.client_manager.network
         floating_ip = client.find_ip(
             parsed_args.floating_ip,
@@ -243,7 +243,7 @@ class DeleteFloatingIPPortForwarding(com
         if result > 0:
             total = len(parsed_args.port_forwarding_id)
             msg = _(
-                "%(result)s of %(total)s Port forwarding failed " "to delete."
+                "%(result)s of %(total)s Port forwarding failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -280,7 +280,7 @@ class ListFloatingIPPortForwarding(comma
         )
         parser.add_argument(
             '--protocol',
-            metavar='protocol',
+            metavar='<protocol>',
             help=_("Filter the list result by the port protocol"),
         )
 
@@ -409,7 +409,7 @@ class SetFloatingIPPortForwarding(common
             '--description',
             metavar='<description>',
             help=_(
-                "A text to describe/contextualize the use of "
+                "Text to describe/contextualize the use of "
                 "the port forwarding configuration"
             ),
         )
diff -pruN 7.4.0-3/openstackclient/network/v2/ip_availability.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/ip_availability.py
--- 7.4.0-3/openstackclient/network/v2/ip_availability.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/ip_availability.py	2025-07-07 22:41:56.000000000 +0000
@@ -26,10 +26,9 @@ _formatters = {
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['id', 'name', 'location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
diff -pruN 7.4.0-3/openstackclient/network/v2/l3_conntrack_helper.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/l3_conntrack_helper.py
--- 7.4.0-3/openstackclient/network/v2/l3_conntrack_helper.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/l3_conntrack_helper.py	2025-07-07 22:41:56.000000000 +0000
@@ -25,10 +25,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -66,8 +65,7 @@ class CreateConntrackHelper(command.Show
             required=True,
             metavar='<protocol>',
             help=_(
-                'The network protocol for the netfilter conntrack target '
-                'rule'
+                'The network protocol for the netfilter conntrack target rule'
             ),
         )
         parser.add_argument(
@@ -99,7 +97,7 @@ class DeleteConntrackHelper(command.Comm
         parser.add_argument(
             'router',
             metavar='<router>',
-            help=_('Router that the conntrack helper belong to'),
+            help=_('Router that the conntrack helper belongs to'),
         )
         parser.add_argument(
             'conntrack_helper_id',
@@ -147,7 +145,7 @@ class ListConntrackHelper(command.Lister
         parser.add_argument(
             'router',
             metavar='<router>',
-            help=_('Router that the conntrack helper belong to'),
+            help=_('Router that the conntrack helper belongs to'),
         )
         parser.add_argument(
             '--helper',
@@ -158,8 +156,7 @@ class ListConntrackHelper(command.Lister
             '--protocol',
             metavar='<protocol>',
             help=_(
-                'The network protocol for the netfilter conntrack target '
-                'rule'
+                'The network protocol for the netfilter conntrack target rule'
             ),
         )
         parser.add_argument(
@@ -210,7 +207,7 @@ class SetConntrackHelper(command.Command
         parser.add_argument(
             'router',
             metavar='<router>',
-            help=_('Router that the conntrack helper belong to'),
+            help=_('Router that the conntrack helper belongs to'),
         )
         parser.add_argument(
             'conntrack_helper_id',
@@ -226,8 +223,7 @@ class SetConntrackHelper(command.Command
             '--protocol',
             metavar='<protocol>',
             help=_(
-                'The network protocol for the netfilter conntrack target '
-                'rule'
+                'The network protocol for the netfilter conntrack target rule'
             ),
         )
         parser.add_argument(
@@ -257,7 +253,7 @@ class ShowConntrackHelper(command.ShowOn
         parser.add_argument(
             'router',
             metavar='<router>',
-            help=_('Router that the conntrack helper belong to'),
+            help=_('Router that the conntrack helper belongs to'),
         )
         parser.add_argument(
             'conntrack_helper_id',
diff -pruN 7.4.0-3/openstackclient/network/v2/local_ip.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/local_ip.py
--- 7.4.0-3/openstackclient/network/v2/local_ip.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/local_ip.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,10 +28,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -74,30 +73,32 @@ class CreateLocalIP(command.ShowOne):
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
         parser.add_argument(
-            '--name', metavar="<name>", help=_("New local IP name")
+            '--name', metavar="<name>", help=_("New Local IP name")
         )
         parser.add_argument(
             '--description',
             metavar="<description>",
-            help=_("New local IP description"),
+            help=_("Description for Local IP"),
         )
         parser.add_argument(
             '--network',
             metavar='<network>',
-            help=_("Network to allocate Local IP (name or ID)"),
+            help=_("Network to allocate Local IP from (name or ID)"),
         )
         parser.add_argument(
             '--local-port',
             metavar='<local-port>',
-            help=_("Port to allocate Local IP (name or ID)"),
+            help=_("Port to allocate Local IP from (name or ID)"),
         )
         parser.add_argument(
             "--local-ip-address",
             metavar="<local-ip-address>",
-            help=_("IP address or CIDR "),
+            help=_("IP address or CIDR for Local IP"),
         )
         parser.add_argument(
-            '--ip-mode', metavar='<ip-mode>', help=_("local IP ip mode")
+            '--ip-mode',
+            metavar='<ip-mode>',
+            help=_("IP mode to use for Local IP"),
         )
 
         identity_common.add_project_domain_option_to_parser(parser)
@@ -116,7 +117,7 @@ class CreateLocalIP(command.ShowOne):
 
 
 class DeleteLocalIP(command.Command):
-    _description = _("Delete local IP(s)")
+    _description = _("Delete Local IP(s)")
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
@@ -149,14 +150,15 @@ class DeleteLocalIP(command.Command):
 
         if result > 0:
             total = len(parsed_args.local_ip)
-            msg = _(
-                "%(result)s of %(total)s local IPs failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s local IPs failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
 class SetLocalIP(command.Command):
-    _description = _("Set local ip properties")
+    _description = _("Set Local IP properties")
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
@@ -171,7 +173,7 @@ class SetLocalIP(command.Command):
         parser.add_argument(
             '--description',
             metavar="<description>",
-            help=_('Set local IP description'),
+            help=_('Set Local IP description'),
         )
         return parser
 
@@ -188,7 +190,7 @@ class SetLocalIP(command.Command):
 
 
 class ListLocalIP(command.Lister):
-    _description = _("List local IPs")
+    _description = _("List Local IPs")
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
@@ -196,36 +198,32 @@ class ListLocalIP(command.Lister):
         parser.add_argument(
             '--name',
             metavar='<name>',
-            help=_("List only local IPs of given name in output"),
+            help=_("List only Local IPs of given name in output"),
         )
         parser.add_argument(
             '--project',
             metavar="<project>",
-            help=_(
-                "List Local IPs according to their project " "(name or ID)"
-            ),
+            help=_("List Local IPs according to their project (name or ID)"),
         )
         parser.add_argument(
             '--network',
             metavar='<network>',
-            help=_(
-                "List Local IP(s) according to " "given network (name or ID)"
-            ),
+            help=_("List Local IP(s) according to given network (name or ID)"),
         )
         parser.add_argument(
             '--local-port',
             metavar='<local-port>',
-            help=_("List Local IP(s) according to " "given port (name or ID)"),
+            help=_("List Local IP(s) according to given port (name or ID)"),
         )
         parser.add_argument(
             '--local-ip-address',
             metavar='<local-ip-address>',
-            help=_("List Local IP(s) according to " "given Local IP Address"),
+            help=_("List Local IP(s) according to given Local IP Address"),
         )
         parser.add_argument(
             '--ip-mode',
             metavar='<ip_mode>',
-            help=_("List Local IP(s) according to " "given IP mode"),
+            help=_("List Local IP(s) according to given IP mode"),
         )
 
         identity_common.add_project_domain_option_to_parser(parser)
@@ -295,7 +293,7 @@ class ListLocalIP(command.Lister):
 
 
 class ShowLocalIP(command.ShowOne):
-    _description = _("Display local IP details")
+    _description = _("Display Local IP details")
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
diff -pruN 7.4.0-3/openstackclient/network/v2/local_ip_association.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/local_ip_association.py
--- 7.4.0-3/openstackclient/network/v2/local_ip_association.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/local_ip_association.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,10 +28,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'name', 'id', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -44,7 +43,7 @@ class CreateLocalIPAssociation(command.S
             'local_ip',
             metavar='<local-ip>',
             help=_(
-                "Local IP that the port association belongs to " "(Name or ID)"
+                "Local IP that the port association belongs to (Name or ID)"
             ),
         )
         parser.add_argument(
@@ -90,7 +89,7 @@ class DeleteLocalIPAssociation(command.C
             'local_ip',
             metavar="<local-ip>",
             help=_(
-                "Local IP that the port association belongs to " "(Name or ID)"
+                "Local IP that the port association belongs to (Name or ID)"
             ),
         )
         parser.add_argument(
@@ -151,7 +150,7 @@ class ListLocalIPAssociation(command.Lis
             '--fixed-port',
             metavar='<fixed-port>',
             help=_(
-                "Filter the list result by the ID or name of " "the fixed port"
+                "Filter the list result by the ID or name of the fixed port"
             ),
         )
         parser.add_argument(
diff -pruN 7.4.0-3/openstackclient/network/v2/ndp_proxy.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/ndp_proxy.py
--- 7.4.0-3/openstackclient/network/v2/ndp_proxy.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/ndp_proxy.py	2025-07-07 22:41:56.000000000 +0000
@@ -29,10 +29,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -69,7 +68,7 @@ class CreateNDPProxy(command.ShowOne):
             '--description',
             metavar='<description>',
             help=_(
-                "A text to describe/contextualize the use of the "
+                "Text to describe/contextualize the use of the "
                 "NDP proxy configuration"
             ),
         )
@@ -124,13 +123,13 @@ class DeleteNDPProxy(command.Command):
             except Exception as e:
                 result += 1
                 LOG.error(
-                    _("Failed to delete NDP proxy " "'%(ndp_proxy)s': %(e)s"),
+                    _("Failed to delete NDP proxy '%(ndp_proxy)s': %(e)s"),
                     {'ndp_proxy': ndp_proxy, 'e': e},
                 )
         if result > 0:
             total = len(parsed_args.ndp_proxy)
             msg = _(
-                "%(result)s of %(total)s NDP proxies failed " "to delete."
+                "%(result)s of %(total)s NDP proxies failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -156,18 +155,18 @@ class ListNDPProxy(command.Lister):
         )
         parser.add_argument(
             '--ip-address',
-            metavar='ip-address',
-            help=_("List only NDP proxies according to their IPv6 address"),
+            metavar='<ip-address>',
+            help=_("List only NDP proxies associated to this IPv6 address"),
         )
         parser.add_argument(
             '--project',
             metavar='<project>',
-            help=_("List NDP proxies according to their project (name or ID)"),
+            help=_("List only NDP proxies of given project (name or ID)"),
         )
         parser.add_argument(
             '--name',
             metavar='<name>',
-            help=_("List NDP proxies according to their name"),
+            help=_("List only NDP proxies of given name"),
         )
 
         identity_common.add_project_domain_option_to_parser(parser)
@@ -247,7 +246,7 @@ class SetNDPProxy(command.Command):
             '--description',
             metavar='<description>',
             help=_(
-                "A text to describe/contextualize the use of "
+                "Text to describe/contextualize the use of "
                 "the NDP proxy configuration"
             ),
         )
diff -pruN 7.4.0-3/openstackclient/network/v2/network.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network.py
--- 7.4.0-3/openstackclient/network/v2/network.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network.py	2025-07-07 22:41:56.000000000 +0000
@@ -68,8 +68,7 @@ def _get_columns_network(item):
 
 
 def _get_columns_compute(item):
-    column_map = {}
-    return utils.get_osc_show_columns_for_sdk_resource(item, column_map)
+    return utils.get_osc_show_columns_for_sdk_resource(item, {})
 
 
 def _get_attrs_network(client_manager, parsed_args):
@@ -166,7 +165,7 @@ def _add_additional_network_options(pars
         help=_(
             "The physical mechanism by which the virtual network "
             "is implemented. For example: "
-            "flat, geneve, gre, local, vlan, vxlan."
+            "flat, geneve, gre, local, vlan or vxlan."
         ),
     )
     parser.add_argument(
@@ -292,8 +291,8 @@ class CreateNetwork(
             action='store_true',
             help=self.enhance_help_neutron(
                 _(
-                    "The network has an external routing facility that's not "
-                    "managed by Neutron and can be used as in: "
+                    "The network has an external routing facility that is not "
+                    "managed by Neutron and can be used. For example: "
                     "openstack router set --external-gateway NETWORK "
                     "(external-net extension required)"
                 )
@@ -355,17 +354,14 @@ class CreateNetwork(
             '--qinq-vlan',
             action='store_true',
             help=self.enhance_help_neutron(
-                _("Enable VLAN QinQ (S-Tag ethtype 0x8a88) " "for the network")
+                _("Enable VLAN QinQ (S-Tag ethtype 0x8a88) for the network")
             ),
         )
         vlan_qinq_grp.add_argument(
             '--no-qinq-vlan',
             action='store_true',
             help=self.enhance_help_neutron(
-                _(
-                    "Disable VLAN QinQ (S-Tag ethtype 0x8a88) "
-                    "for the network"
-                )
+                _("Disable VLAN QinQ (S-Tag ethtype 0x8a88) for the network")
             ),
         )
 
@@ -537,7 +533,7 @@ class ListNetwork(common.NetworkAndCompu
                 _(
                     "List networks according to their physical mechanisms. "
                     "The supported options are: flat, geneve, gre, local, "
-                    "vlan, vxlan."
+                    "vlan and vxlan."
                 )
             ),
         )
@@ -576,7 +572,7 @@ class ListNetwork(common.NetworkAndCompu
     def take_action_network(self, client, parsed_args):
         identity_client = self.app.client_manager.identity
         if parsed_args.long:
-            columns = (
+            columns: tuple[str, ...] = (
                 'id',
                 'name',
                 'status',
@@ -589,7 +585,7 @@ class ListNetwork(common.NetworkAndCompu
                 'availability_zones',
                 'tags',
             )
-            column_headers = (
+            column_headers: tuple[str, ...] = (
                 'ID',
                 'Name',
                 'Status',
@@ -789,10 +785,10 @@ class SetNetwork(common.NeutronCommandWi
             '--external',
             action='store_true',
             help=_(
-                "The network has an external routing facility that's not "
-                "managed by Neutron and can be used as in: "
+                "The network has an external routing facility that is not "
+                "managed by Neutron and can be used. For example: "
                 "openstack router set --external-gateway NETWORK "
-                "(external-net extension required)"
+                "(external-net extension required)."
             ),
         )
         external_router_grp.add_argument(
diff -pruN 7.4.0-3/openstackclient/network/v2/network_agent.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_agent.py
--- 7.4.0-3/openstackclient/network/v2/network_agent.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_agent.py	2025-07-07 22:41:56.000000000 +0000
@@ -155,7 +155,7 @@ class DeleteNetworkAgent(command.Command
         if result > 0:
             total = len(parsed_args.network_agent)
             msg = _(
-                "%(result)s of %(total)s network agents failed " "to delete."
+                "%(result)s of %(total)s network agents failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -164,32 +164,37 @@ class DeleteNetworkAgent(command.Command
 # OSC minimum requirements include SDK 1.0.
 class ListNetworkAgent(command.Lister):
     _description = _("List network agents")
+    _supported_agents = {
+        'bgp': 'BGP dynamic routing agent',
+        'dhcp': 'DHCP agent',
+        'open-vswitch': 'Open vSwitch agent',
+        'linux-bridge': 'Linux bridge agent',
+        'ofa': 'OFA driver agent',
+        'l3': 'L3 agent',
+        'loadbalancer': 'Loadbalancer agent',
+        'metering': 'Metering agent',
+        'metadata': 'Metadata agent',
+        'macvtap': 'Macvtap agent',
+        'nic': 'NIC Switch agent',
+        'baremetal': 'Baremetal Node',
+        'ovn-controller': 'OVN Controller agent',
+        'ovn-controller-gateway': 'OVN Controller Gateway agent',
+        'ovn-metadata': 'OVN Metadata agent',
+        'ovn-agent': 'OVN Neutron agent',
+    }
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
+        supported_agents = ','.join(self._supported_agents.keys())
         parser.add_argument(
             '--agent-type',
             metavar='<agent-type>',
-            choices=[
-                "bgp",
-                "dhcp",
-                "open-vswitch",
-                "linux-bridge",
-                "ofa",
-                "l3",
-                "loadbalancer",
-                "metering",
-                "metadata",
-                "macvtap",
-                "nic",
-                "baremetal",
-            ],
+            choices=list(self._supported_agents.keys()),
             help=_(
                 "List only agents with the specified agent type. "
-                "The supported agent types are: bgp, dhcp, open-vswitch, "
-                "linux-bridge, ofa, l3, loadbalancer, metering, "
-                "metadata, macvtap, nic, baremetal."
-            ),
+                "The supported agent types are: %(supported_agents)s."
+            )
+            % {'supported_agents': supported_agents},
         )
         parser.add_argument(
             '--host',
@@ -218,7 +223,7 @@ class ListNetworkAgent(command.Lister):
 
     def take_action(self, parsed_args):
         client = self.app.client_manager.network
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'agent_type',
             'host',
@@ -227,7 +232,7 @@ class ListNetworkAgent(command.Lister):
             'is_admin_state_up',
             'binary',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Agent Type',
             'Host',
@@ -237,21 +242,6 @@ class ListNetworkAgent(command.Lister):
             'Binary',
         )
 
-        key_value = {
-            'bgp': 'BGP dynamic routing agent',
-            'dhcp': 'DHCP agent',
-            'open-vswitch': 'Open vSwitch agent',
-            'linux-bridge': 'Linux bridge agent',
-            'ofa': 'OFA driver agent',
-            'l3': 'L3 agent',
-            'loadbalancer': 'Loadbalancer agent',
-            'metering': 'Metering agent',
-            'metadata': 'Metadata agent',
-            'macvtap': 'Macvtap agent',
-            'nic': 'NIC Switch agent',
-            'baremetal': 'Baremetal Node',
-        }
-
         filters = {}
 
         if parsed_args.network is not None:
@@ -269,7 +259,9 @@ class ListNetworkAgent(command.Lister):
             data = client.routers_hosting_l3_agents(router)
         else:
             if parsed_args.agent_type is not None:
-                filters['agent_type'] = key_value[parsed_args.agent_type]
+                filters['agent_type'] = self._supported_agents[
+                    parsed_args.agent_type
+                ]
             if parsed_args.host is not None:
                 filters['host'] = parsed_args.host
 
diff -pruN 7.4.0-3/openstackclient/network/v2/network_auto_allocated_topology.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_auto_allocated_topology.py
--- 7.4.0-3/openstackclient/network/v2/network_auto_allocated_topology.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_auto_allocated_topology.py	2025-07-07 22:41:56.000000000 +0000
@@ -25,10 +25,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['name', 'location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -71,7 +70,7 @@ class CreateAutoAllocatedTopology(comman
             metavar='<project>',
             help=_(
                 "Return the auto allocated topology for a given project. "
-                "Default is current project"
+                "Default is current project."
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
@@ -89,7 +88,7 @@ class CreateAutoAllocatedTopology(comman
             default=True,
             help=_(
                 "If topology exists returns the topology's "
-                "information (Default)"
+                "information (default)"
             ),
         )
 
@@ -132,7 +131,7 @@ class DeleteAutoAllocatedTopology(comman
             metavar='<project>',
             help=_(
                 'Delete auto allocated topology for a given project. '
-                'Default is the current project'
+                'Default is the current project.'
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
diff -pruN 7.4.0-3/openstackclient/network/v2/network_flavor.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_flavor.py
--- 7.4.0-3/openstackclient/network/v2/network_flavor.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_flavor.py	2025-07-07 22:41:56.000000000 +0000
@@ -102,7 +102,7 @@ class CreateNetworkFlavor(command.ShowOn
             metavar="<service-type>",
             required=True,
             help=_(
-                'Service type to which the flavor applies to: e.g. VPN '
+                'Service type to which the flavor applies. For example: VPN '
                 '(See openstack network service provider list for loaded '
                 'examples.)'
             ),
diff -pruN 7.4.0-3/openstackclient/network/v2/network_flavor_profile.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_flavor_profile.py
--- 7.4.0-3/openstackclient/network/v2/network_flavor_profile.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_flavor_profile.py	2025-07-07 22:41:56.000000000 +0000
@@ -79,14 +79,14 @@ class CreateNetworkFlavorProfile(
             '--driver',
             help=_(
                 "Python module path to driver. This becomes "
-                "required if --metainfo is missing and vice versa"
+                "required if --metainfo is missing and vice-versa."
             ),
         )
         parser.add_argument(
             '--metainfo',
             help=_(
                 "Metainfo for the flavor profile. This becomes "
-                "required if --driver is missing and vice versa"
+                "required if --driver is missing and vice-versa."
             ),
         )
 
@@ -146,7 +146,7 @@ class DeleteNetworkFlavorProfile(command
         if result > 0:
             total = len(parsed_args.flavor_profile)
             msg = _(
-                "%(result)s of %(total)s flavor_profiles failed " "to delete."
+                "%(result)s of %(total)s flavor_profiles failed to delete."
             ) % {"result": result, "total": total}
             raise exceptions.CommandError(msg)
 
@@ -217,14 +217,14 @@ class SetNetworkFlavorProfile(common.Neu
             '--driver',
             help=_(
                 "Python module path to driver. This becomes "
-                "required if --metainfo is missing and vice versa"
+                "required if --metainfo is missing and vice-versa."
             ),
         )
         parser.add_argument(
             '--metainfo',
             help=_(
                 "Metainfo for the flavor profile. This becomes "
-                "required if --driver is missing and vice versa"
+                "required if --driver is missing and vice-versa."
             ),
         )
 
diff -pruN 7.4.0-3/openstackclient/network/v2/network_meter.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_meter.py
--- 7.4.0-3/openstackclient/network/v2/network_meter.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_meter.py	2025-07-07 22:41:56.000000000 +0000
@@ -70,7 +70,7 @@ class CreateMeter(command.ShowOne, commo
         parser.add_argument(
             '--description',
             metavar='<description>',
-            help=_("Create description for meter"),
+            help=_("Description for meter"),
         )
         parser.add_argument(
             '--project',
@@ -139,12 +139,12 @@ class DeleteMeter(command.Command):
             except Exception as e:
                 result += 1
                 LOG.error(
-                    _("Failed to delete meter with " "ID '%(meter)s': %(e)s"),
+                    _("Failed to delete meter with ID '%(meter)s': %(e)s"),
                     {"meter": meter, "e": e},
                 )
         if result > 0:
             total = len(parsed_args.meter)
-            msg = _("%(result)s of %(total)s meters failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s meters failed to delete.") % {
                 "result": result,
                 "total": total,
             }
diff -pruN 7.4.0-3/openstackclient/network/v2/network_meter_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_meter_rule.py
--- 7.4.0-3/openstackclient/network/v2/network_meter_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_meter_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,6 +14,7 @@
 """Meter Rule Implementations"""
 
 import logging
+import typing as ty
 
 from osc_lib.command import command
 from osc_lib import exceptions
@@ -27,15 +28,14 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
 def _get_attrs(client_manager, parsed_args):
-    attrs = {}
+    attrs: dict[str, ty.Any] = {}
 
     if parsed_args.exclude:
         attrs['excluded'] = True
@@ -168,17 +168,14 @@ class DeleteMeterRule(command.Command):
             except Exception as e:
                 result += 1
                 LOG.error(
-                    _(
-                        "Failed to delete meter rule with "
-                        "ID '%(id)s': %(e)s"
-                    ),
+                    _("Failed to delete meter rule with ID '%(id)s': %(e)s"),
                     {"id": id, "e": e},
                 )
 
         if result > 0:
             total = len(parsed_args.meter_rule_id)
             msg = _(
-                "%(result)s of %(total)s meter rules failed " "to delete."
+                "%(result)s of %(total)s meter rules failed to delete."
             ) % {"result": result, "total": total}
             raise exceptions.CommandError(msg)
 
diff -pruN 7.4.0-3/openstackclient/network/v2/network_qos_policy.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_qos_policy.py
--- 7.4.0-3/openstackclient/network/v2/network_qos_policy.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_qos_policy.py	2025-07-07 22:41:56.000000000 +0000
@@ -174,7 +174,7 @@ class DeleteNetworkQosPolicy(command.Com
         if result > 0:
             total = len(parsed_args.policy)
             msg = _(
-                "%(result)s of %(total)s QoS policies failed " "to delete."
+                "%(result)s of %(total)s QoS policies failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -190,7 +190,7 @@ class ListNetworkQosPolicy(command.Liste
             '--project',
             metavar='<project>',
             help=_(
-                "List qos policies according to their project (name or ID)"
+                "List QoS policies according to their project (name or ID)"
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
@@ -198,12 +198,12 @@ class ListNetworkQosPolicy(command.Liste
         shared_group.add_argument(
             '--share',
             action='store_true',
-            help=_("List qos policies shared between projects"),
+            help=_("List QoS policies shared between projects"),
         )
         shared_group.add_argument(
             '--no-share',
             action='store_true',
-            help=_("List qos policies not shared between projects"),
+            help=_("List QoS policies not shared between projects"),
         )
         return parser
 
diff -pruN 7.4.0-3/openstackclient/network/v2/network_qos_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_qos_rule.py
--- 7.4.0-3/openstackclient/network/v2/network_qos_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_qos_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -73,10 +73,9 @@ ACTION_SHOW = 'get'
 
 
 def _get_columns(item):
-    column_map = {}
-    hidden_columns = ['location', 'tenant_id']
+    hidden_columns = ['location', 'name', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -149,14 +148,6 @@ def _get_attrs(network_client, parsed_ar
     return attrs
 
 
-def _get_item_properties(item, fields):
-    """Return a tuple containing the item properties."""
-    row = []
-    for field in fields:
-        row.append(item.get(field, ''))
-    return tuple(row)
-
-
 def _rule_action_call(client, action, rule_type):
     rule_type = rule_type.replace('-', '_')
     func_name = f'{action}_qos_{rule_type}_rule'
@@ -358,10 +349,10 @@ class ListNetworkQosRule(command.Lister)
         qos = client.find_qos_policy(
             parsed_args.qos_policy, ignore_missing=False
         )
-        data = qos.rules
+
         return (
             column_headers,
-            (_get_item_properties(s, columns) for s in data),
+            (utils.get_dict_properties(s, columns) for s in qos.rules),
         )
 
 
@@ -378,7 +369,7 @@ class SetNetworkQosRule(common.NeutronCo
         parser.add_argument(
             'id',
             metavar='<rule-id>',
-            help=_('Network QoS rule to delete (ID)'),
+            help=_('Network QoS rule to set (ID)'),
         )
         _add_rule_arguments(parser)
         return parser
@@ -424,7 +415,7 @@ class ShowNetworkQosRule(command.ShowOne
         parser.add_argument(
             'id',
             metavar='<rule-id>',
-            help=_('Network QoS rule to delete (ID)'),
+            help=_('Network QoS rule to show (ID)'),
         )
         return parser
 
@@ -442,7 +433,7 @@ class ShowNetworkQosRule(command.ShowOne
                 rule_id, qos.id
             )
         except Exception as e:
-            msg = _('Failed to set Network QoS rule ID "%(rule)s": %(e)s') % {
+            msg = _('Failed to show Network QoS rule ID "%(rule)s": %(e)s') % {
                 'rule': rule_id,
                 'e': e,
             }
diff -pruN 7.4.0-3/openstackclient/network/v2/network_rbac.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_rbac.py
--- 7.4.0-3/openstackclient/network/v2/network_rbac.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_rbac.py	2025-07-07 22:41:56.000000000 +0000
@@ -147,7 +147,7 @@ class CreateNetworkRBAC(command.ShowOne,
         target_project_group.add_argument(
             '--target-all-projects',
             action='store_true',
-            help=_('Allow creating RBAC policy for all projects.'),
+            help=_('Allow creating RBAC policy for all projects'),
         )
         parser.add_argument(
             '--target-project-domain',
@@ -212,7 +212,7 @@ class DeleteNetworkRBAC(command.Command)
         if result > 0:
             total = len(parsed_args.rbac_policy)
             msg = _(
-                "%(result)s of %(total)s RBAC policies failed " "to delete."
+                "%(result)s of %(total)s RBAC policies failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -265,12 +265,12 @@ class ListNetworkRBAC(command.Lister):
     def take_action(self, parsed_args):
         client = self.app.client_manager.network
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'object_type',
             'object_id',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Object Type',
             'Object ID',
diff -pruN 7.4.0-3/openstackclient/network/v2/network_segment.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_segment.py
--- 7.4.0-3/openstackclient/network/v2/network_segment.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_segment.py	2025-07-07 22:41:56.000000000 +0000
@@ -26,10 +26,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -141,7 +140,7 @@ class DeleteNetworkSegment(command.Comma
         if result > 0:
             total = len(parsed_args.network_segment)
             msg = _(
-                "%(result)s of %(total)s network segments failed " "to delete."
+                "%(result)s of %(total)s network segments failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -178,14 +177,14 @@ class ListNetworkSegment(command.Lister)
             filters = {'network_id': _network.id}
         data = network_client.segments(**filters)
 
-        headers = (
+        headers: tuple[str, ...] = (
             'ID',
             'Name',
             'Network',
             'Network Type',
             'Segment',
         )
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             'network_id',
@@ -193,8 +192,8 @@ class ListNetworkSegment(command.Lister)
             'segmentation_id',
         )
         if parsed_args.long:
-            headers = headers + ('Physical Network',)
-            columns = columns + ('physical_network',)
+            headers += ('Physical Network',)
+            columns += ('physical_network',)
 
         return (
             headers,
diff -pruN 7.4.0-3/openstackclient/network/v2/network_segment_range.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_segment_range.py
--- 7.4.0-3/openstackclient/network/v2/network_segment_range.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_segment_range.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,6 +18,7 @@
 
 import itertools
 import logging
+import typing as ty
 
 from osc_lib.command import command
 from osc_lib import exceptions
@@ -32,19 +33,18 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
 def _get_ranges(item):
     item = sorted([int(i) for i in item])
     for a, b in itertools.groupby(enumerate(item), lambda xy: xy[1] - xy[0]):
-        b = list(b)
+        c = list(b)
         yield (
-            f"{b[0][1]}-{b[-1][1]}" if b[0][1] != b[-1][1] else str(b[0][1])
+            f"{c[0][1]}-{c[-1][1]}" if c[0][1] != c[-1][1] else str(c[0][1])
         )
 
 
@@ -59,7 +59,7 @@ def _is_prop_empty(columns, props, prop_
 
 
 def _exchange_dict_keys_with_values(orig_dict):
-    updated_dict = dict()
+    updated_dict: dict[str, ty.Any] = {}
     for k, v in orig_dict.items():
         k = [k]
         if not updated_dict.get(v):
@@ -105,8 +105,7 @@ class CreateNetworkSegmentRange(
             dest="private",
             action="store_true",
             help=_(
-                'Network segment range is assigned specifically to the '
-                'project'
+                'Network segment range is assigned specifically to the project'
             ),
         )
         shared_group.add_argument(
@@ -125,7 +124,7 @@ class CreateNetworkSegmentRange(
             metavar='<project>',
             help=_(
                 'Network segment range owner (name or ID). Optional when '
-                'the segment range is shared'
+                'the segment range is shared.'
             ),
         )
         identity_common.add_project_domain_option_to_parser(parser)
@@ -196,8 +195,7 @@ class CreateNetworkSegmentRange(
             and parsed_args.physical_network
         ):
             msg = _(
-                "--physical-network is only allowed with --network-type "
-                "vlan"
+                "--physical-network is only allowed with --network-type vlan"
             )
             raise exceptions.CommandError(msg)
 
@@ -323,7 +321,7 @@ class ListNetworkSegmentRange(command.Li
             '--unused',
             action='store_true',
             help=_(
-                'List network segment ranges that have segments ' 'not in use'
+                'List network segment ranges that have segments not in use'
             ),
         )
         available_group = parser.add_mutually_exclusive_group()
@@ -353,10 +351,9 @@ class ListNetworkSegmentRange(command.Li
             ) % {'e': e}
             raise exceptions.CommandError(msg)
 
-        filters = {}
-        data = network_client.network_segment_ranges(**filters)
+        data = network_client.network_segment_ranges()
 
-        headers = (
+        headers: tuple[str, ...] = (
             'ID',
             'Name',
             'Default',
@@ -367,7 +364,7 @@ class ListNetworkSegmentRange(command.Li
             'Minimum ID',
             'Maximum ID',
         )
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             'default',
@@ -389,16 +386,16 @@ class ListNetworkSegmentRange(command.Li
             # should be listed in output.
             parsed_args.long = True
         if parsed_args.long:
-            headers = headers + (
+            headers += (
                 'Used',
                 'Available',
             )
-            columns = columns + (
+            columns += (
                 'used',
                 'available',
             )
 
-        display_props = tuple()
+        display_props: tuple[str, ...] = tuple()
         for s in data:
             props = utils.get_item_properties(s, columns)
             if (
@@ -457,8 +454,7 @@ class SetNetworkSegmentRange(common.Neut
             )
         except Exception as e:
             msg = _(
-                'Network segment range set not supported by '
-                'Network API: %(e)s'
+                'Network segment range set not supported by Network API: %(e)s'
             ) % {'e': e}
             raise exceptions.CommandError(msg)
 
diff -pruN 7.4.0-3/openstackclient/network/v2/network_trunk.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_trunk.py
--- 7.4.0-3/openstackclient/network/v2/network_trunk.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/network_trunk.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@
 """Network trunk and subports action implementations"""
 
 import logging
+import typing as ty
 
 from cliff import columns as cliff_columns
 from osc_lib.cli import format_columns
@@ -69,8 +70,8 @@ class CreateNetworkTrunk(command.ShowOne
             help=_(
                 "Subport to add. Subport is of form "
                 "'port=<name or ID>,segmentation-type=<segmentation-type>,"
-                "segmentation-id=<segmentation-ID>' (--subport) option "
-                "can be repeated"
+                "segmentation-id=<segmentation-ID>' (repeat option "
+                "to add multiple subports)"
             ),
         )
         admin_group = parser.add_mutually_exclusive_group()
@@ -128,7 +129,7 @@ class DeleteNetworkTrunk(command.Command
                 )
         if result > 0:
             total = len(parsed_args.trunk)
-            msg = _("%(result)s of %(total)s trunks failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s trunks failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -151,8 +152,8 @@ class ListNetworkTrunk(command.Lister):
     def take_action(self, parsed_args):
         client = self.app.client_manager.network
         data = client.trunks()
-        headers = ('ID', 'Name', 'Parent Port', 'Description')
-        columns = ('id', 'name', 'port_id', 'description')
+        headers: tuple[str, ...] = ('ID', 'Name', 'Parent Port', 'Description')
+        columns: tuple[str, ...] = ('id', 'name', 'port_id', 'description')
         if parsed_args.long:
             headers += (
                 'Status',
@@ -199,9 +200,9 @@ class SetNetworkTrunk(command.Command):
             required_keys=['port'],
             help=_(
                 "Subport to add. Subport is of form "
-                "'port=<name or ID>,segmentation-type=<segmentation-type>"
-                ",segmentation-id=<segmentation-ID>' (--subport) option "
-                "can be repeated"
+                "'port=<name or ID>,segmentation-type=<segmentation-type>,"
+                "segmentation-id=<segmentation-ID>' (repeat option "
+                "to add multiple subports)"
             ),
         )
         admin_group = parser.add_mutually_exclusive_group()
@@ -277,8 +278,16 @@ class ListNetworkSubport(command.Lister)
         client = self.app.client_manager.network
         trunk_id = client.find_trunk(parsed_args.trunk)
         data = client.get_trunk_subports(trunk_id)
-        headers = ('Port', 'Segmentation Type', 'Segmentation ID')
-        columns = ('port_id', 'segmentation_type', 'segmentation_id')
+        headers: tuple[str, ...] = (
+            'Port',
+            'Segmentation Type',
+            'Segmentation ID',
+        )
+        columns: tuple[str, ...] = (
+            'port_id',
+            'segmentation_type',
+            'segmentation_id',
+        )
         return (
             headers,
             (
@@ -308,8 +317,8 @@ class UnsetNetworkTrunk(command.Command)
             action='append',
             dest='unset_subports',
             help=_(
-                "Subport to delete (name or ID of the port) "
-                "(--subport) option can be repeated"
+                "Subport to unset (name or ID of the port) "
+                "(repeat option to unset multiple subports)"
             ),
         )
         return parser
@@ -328,15 +337,14 @@ _formatters = {
 
 
 def _get_columns(item):
-    column_map = {}
     hidden_columns = ['location', 'tenant_id']
     return osc_utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
 def _get_attrs_for_trunk(client_manager, parsed_args):
-    attrs = {}
+    attrs: dict[str, ty.Any] = {}
     if parsed_args.name is not None:
         attrs['name'] = str(parsed_args.name)
     if parsed_args.description is not None:
@@ -393,7 +401,7 @@ def _format_subports(client_manager, sub
 
 
 def _get_attrs_for_subports(client_manager, parsed_args):
-    attrs = {}
+    attrs = []
     if 'set_subports' in parsed_args and parsed_args.set_subports is not None:
         attrs = _format_subports(client_manager, parsed_args.set_subports)
     if (
diff -pruN 7.4.0-3/openstackclient/network/v2/port.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/port.py
--- 7.4.0-3/openstackclient/network/v2/port.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/port.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@ import argparse
 import copy
 import json
 import logging
+import typing as ty
 
 from cliff import columns as cliff_columns
 from osc_lib.cli import format_columns
@@ -39,6 +40,8 @@ class AdminStateColumn(cliff_columns.For
 
 
 class SubPortColumn(format_columns.ListDictColumn):
+    _value: ty.Any
+
     def _retrieve_subports(self):
         if isinstance(self._value, dict):
             self._value = self._value['sub_ports']
@@ -347,8 +350,8 @@ def _add_updatable_args(parser, create=F
         help=_(
             "VNIC type for this port (direct | direct-physical | "
             "macvtap | normal | baremetal | virtio-forwarder | vdpa | "
-            "remote-managed, "
-            "default: normal)"
+            "remote-managed) "
+            "(default: normal)"
         ),
     )
     parser.add_argument(
@@ -368,8 +371,7 @@ def _add_updatable_args(parser, create=F
         '--dns-name',
         metavar='<dns-name>',
         help=_(
-            "Set DNS name for this port "
-            "(requires DNS integration extension)"
+            "Set DNS name for this port (requires DNS integration extension)"
         ),
     )
     numa_affinity_policy_group = parser.add_mutually_exclusive_group()
@@ -406,7 +408,7 @@ def _add_updatable_args(parser, create=F
             '(requires port-hints extension) '
             '(requires port-hint-ovs-tx-steering extension for alias: '
             'ovs-tx-steering) '
-            '(repeat option to set multiple hints)'
+            '(repeat option to set multiple hints).'
         ),
     )
     port_trusted = parser.add_mutually_exclusive_group()
@@ -416,7 +418,7 @@ def _add_updatable_args(parser, create=F
         help=_(
             "Set port to be trusted. This will be populated into the "
             "'binding:profile' dictionary and passed to the services "
-            "which expect it in this dictionary (for example, Nova)"
+            "which expect it in this dictionary (for example, Nova)."
         ),
     )
     port_trusted.add_argument(
@@ -425,7 +427,7 @@ def _add_updatable_args(parser, create=F
         help=_(
             "Set port to be not trusted. This will be populated into the "
             "'binding:profile' dictionary and passed to the services "
-            "which expect it in this dictionary (for example, Nova)"
+            "which expect it in this dictionary (for example, Nova)."
         ),
     )
 
@@ -512,7 +514,7 @@ class CreatePort(command.ShowOne, common
         fixed_ip.add_argument(
             '--no-fixed-ip',
             action='store_true',
-            help=_("No IP or subnet for this port."),
+            help=_("No IP or subnet set for this port"),
         )
         parser.add_argument(
             '--binding-profile',
@@ -520,8 +522,8 @@ class CreatePort(command.ShowOne, common
             action=JSONKeyValueAction,
             help=_(
                 "Custom data to be passed as binding:profile. Data may "
-                "be passed as <key>=<value> or JSON. "
-                "(repeat option to set multiple binding:profile data)"
+                "be passed as <key>=<value> or JSON "
+                "(repeat option to set multiple binding:profile data)."
             ),
         )
         admin_group = parser.add_mutually_exclusive_group()
@@ -596,7 +598,7 @@ class CreatePort(command.ShowOne, common
         port_security.add_argument(
             '--enable-port-security',
             action='store_true',
-            help=_("Enable port security for this port (Default)"),
+            help=_("Enable port security for this port (default)"),
         )
         port_security.add_argument(
             '--disable-port-security',
@@ -619,7 +621,7 @@ class CreatePort(command.ShowOne, common
         parser.add_argument(
             '--device-profile',
             metavar='<device-profile>',
-            help=_('Cyborg port device profile'),
+            help=_('Port device profile'),
         )
         parser.add_argument(
             '--hardware-offload-type',
@@ -753,7 +755,7 @@ class DeletePort(command.Command):
 
         if result > 0:
             total = len(parsed_args.port)
-            msg = _("%(result)s of %(total)s ports failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s ports failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -901,7 +903,7 @@ class ListPort(command.Lister):
             )
             filters['device_id'] = _router.id
         if parsed_args.server:
-            compute_client = self.app.client_manager.sdk_connection.compute
+            compute_client = self.app.client_manager.compute
             server = compute_client.find_server(
                 parsed_args.server,
                 ignore_missing=False,
@@ -944,15 +946,12 @@ class ListPort(command.Lister):
                 for item in columns
             ]
 
-        headers, attrs = utils.calculate_header_and_attrs(
-            column_headers, columns, parsed_args
-        )
         return (
-            headers,
+            column_headers,
             (
                 utils.get_item_properties(
                     s,
-                    attrs,
+                    columns,
                     formatters=_list_formatters,
                 )
                 for s in data
@@ -996,7 +995,7 @@ class SetPort(common.NeutronCommandWithE
             '--no-fixed-ip',
             action='store_true',
             help=_(
-                "Clear existing information of fixed IP addresses."
+                "Clear existing information of fixed IP addresses. "
                 "Specify both --fixed-ip and --no-fixed-ip "
                 "to overwrite the current fixed IP addresses."
             ),
@@ -1007,8 +1006,8 @@ class SetPort(common.NeutronCommandWithE
             action=JSONKeyValueAction,
             help=_(
                 "Custom data to be passed as binding:profile. Data may "
-                "be passed as <key>=<value> or JSON. "
-                "(repeat option to set multiple binding:profile data)"
+                "be passed as <key>=<value> or JSON "
+                "(repeat option to set multiple binding:profile data)."
             ),
         )
         parser.add_argument(
@@ -1075,8 +1074,8 @@ class SetPort(common.NeutronCommandWithE
             help=_(
                 "Clear existing allowed-address pairs associated "
                 "with this port. "
-                "(Specify both --allowed-address and --no-allowed-address "
-                "to overwrite the current allowed-address pairs)"
+                "Specify both --allowed-address and --no-allowed-address "
+                "to overwrite the current allowed-address pairs."
             ),
         )
         parser.add_argument(
@@ -1100,7 +1099,7 @@ class SetPort(common.NeutronCommandWithE
             help=_(
                 "Set data plane status of this port (ACTIVE | DOWN). "
                 "Unset it to None with the 'port unset' command "
-                "(requires data plane status extension)"
+                "(requires data plane status extension)."
             ),
         )
         uplink_status_group = parser.add_mutually_exclusive_group()
@@ -1262,7 +1261,7 @@ class UnsetPort(common.NeutronUnsetComma
             action='append',
             help=_(
                 "Desired key which should be removed from binding:profile "
-                "(repeat option to unset multiple binding:profile data)"
+                "(repeat option to unset multiple binding:profile keys)"
             ),
         )
         parser.add_argument(
@@ -1298,7 +1297,7 @@ class UnsetPort(common.NeutronUnsetComma
         parser.add_argument(
             '--data-plane-status',
             action='store_true',
-            help=_("Clear existing information of data plane status"),
+            help=_("Clear existing data plane status information"),
         )
         parser.add_argument(
             '--numa-policy',
@@ -1309,13 +1308,13 @@ class UnsetPort(common.NeutronUnsetComma
             '--host',
             action='store_true',
             default=False,
-            help=_("Clear host binding for the port."),
+            help=_("Clear host binding for the port"),
         )
         parser.add_argument(
             '--hints',
             action='store_true',
             default=False,
-            help=_("Clear hints for the port."),
+            help=_("Clear hints for the port"),
         )
         _tag.add_tag_option_to_parser_for_unset(parser, _('port'))
         parser.add_argument(
diff -pruN 7.4.0-3/openstackclient/network/v2/router.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/router.py
--- 7.4.0-3/openstackclient/network/v2/router.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/router.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,6 +18,7 @@ import collections
 import copy
 import json
 import logging
+import typing as ty
 
 from cliff import columns as cliff_columns
 from osc_lib.cli import format_columns
@@ -75,7 +76,7 @@ def _get_columns(item):
     }
     if hasattr(item, 'interfaces_info'):
         column_map['interfaces_info'] = 'interfaces_info'
-    invisible_columns = ['location']
+    invisible_columns = ['location', 'tenant_id']
     if item.is_ha is None:
         invisible_columns.append('is_ha')
         column_map.pop('is_ha')
@@ -104,21 +105,21 @@ def _passed_multiple_gateways(extension_
 
 
 def _get_external_gateway_attrs(client_manager, parsed_args):
-    attrs = {}
+    attrs: dict[str, ty.Any] = {}
 
     if parsed_args.external_gateways:
         external_gateways: collections.defaultdict[str, list[dict]] = (
             collections.defaultdict(list)
         )
         n_client = client_manager.network
-        first_network_id = None
+        first_network_id = ''
 
         for gw_net_name_or_id in parsed_args.external_gateways:
             gateway_info = {}
             gw_net = n_client.find_network(
                 gw_net_name_or_id, ignore_missing=False
             )
-            if first_network_id is None:
+            if not first_network_id:
                 first_network_id = gw_net.id
             gateway_info['network_id'] = gw_net.id
             if 'disable_snat' in parsed_args and parsed_args.disable_snat:
@@ -146,7 +147,7 @@ def _get_external_gateway_attrs(client_m
             for ip_spec in parsed_args.fixed_ips:
                 # If there is only one gateway, this value will represent the
                 # network ID for it, otherwise it will be overridden.
-                ip_net_id = first_network_id
+                ip_net_id: str = first_network_id
 
                 if ip_spec.get('subnet', False):
                     subnet_name_id = ip_spec.pop('subnet')
@@ -258,7 +259,7 @@ def _parser_add_bfd_ecmp_arguments(parse
         action='store_true',
         help=_(
             "Enable BFD sessions for default routes inferred from "
-            "the external gateway port subnets for this router."
+            "the external gateway port subnets for this router"
         ),
     )
     parser.add_argument(
@@ -268,7 +269,7 @@ def _parser_add_bfd_ecmp_arguments(parse
         action='store_false',
         help=_(
             "Disable BFD sessions for default routes inferred from "
-            "the external gateway port subnets for this router."
+            "the external gateway port subnets for this router"
         ),
     )
     parser.add_argument(
@@ -278,7 +279,7 @@ def _parser_add_bfd_ecmp_arguments(parse
         action='store_true',
         help=_(
             "Add ECMP default routes if multiple are available via "
-            "different gateway ports."
+            "different gateway ports"
         ),
     )
     parser.add_argument(
@@ -286,7 +287,7 @@ def _parser_add_bfd_ecmp_arguments(parse
         dest='enable_default_route_ecmp',
         default=None,
         action='store_false',
-        help=_("Add default route only for first gateway port."),
+        help=_("Add default route only for first gateway port"),
     )
 
 
@@ -367,7 +368,7 @@ class AddExtraRoutesToRouter(command.Sho
             metavar='<router>',
             help=_(
                 "Router to which extra static routes "
-                "will be added (name or ID)."
+                "will be added (name or ID)"
             ),
         )
         parser.add_argument(
@@ -382,7 +383,7 @@ class AddExtraRoutesToRouter(command.Sho
                 "destination: destination subnet (in CIDR notation), "
                 "gateway: nexthop IP address. "
                 "Repeat option to add multiple routes. "
-                "Trying to add a route that's already present "
+                "Trying to add a route that is already present "
                 "(exactly, including destination and nexthop) "
                 "in the routing table is allowed and is considered "
                 "a successful operation."
@@ -418,7 +419,7 @@ class RemoveExtraRoutesFromRouter(comman
             metavar='<router>',
             help=_(
                 "Router from which extra static routes "
-                "will be removed (name or ID)."
+                "will be removed (name or ID)"
             ),
         )
         parser.add_argument(
@@ -433,7 +434,7 @@ class RemoveExtraRoutesFromRouter(comman
                 "destination: destination subnet (in CIDR notation), "
                 "gateway: nexthop IP address. "
                 "Repeat option to remove multiple routes. "
-                "Trying to remove a route that's already missing "
+                "Trying to remove a route that is already missing "
                 "(fully, including destination and nexthop) "
                 "from the routing table is allowed and is considered "
                 "a successful operation."
@@ -525,9 +526,9 @@ class CreateRouter(command.ShowOne, comm
             metavar="<network>",
             action='append',
             help=_(
-                "External Network used as router's gateway (name or ID). "
+                "External Network used as router's gateway (name or ID) "
                 "(repeat option to set multiple gateways per router "
-                "if the L3 service plugin in use supports it)."
+                "if the L3 service plugin in use supports it)"
             ),
             dest='external_gateways',
         )
@@ -541,7 +542,7 @@ class CreateRouter(command.ShowOne, comm
                 "Desired IP and/or subnet (name or ID) "
                 "on external gateway: "
                 "subnet=<subnet>,ip-address=<ip-address> "
-                "(repeat option to set multiple fixed IP addresses)."
+                "(repeat option to set multiple fixed IP addresses)"
             ),
         )
         snat_group = parser.add_mutually_exclusive_group()
@@ -581,6 +582,11 @@ class CreateRouter(command.ShowOne, comm
             help=argparse.SUPPRESS,
         )
         _parser_add_bfd_ecmp_arguments(parser)
+        parser.add_argument(
+            '--qos-policy',
+            metavar='<qos-policy>',
+            help=_('Attach QoS policy to router gateway IPs'),
+        )
 
         return parser
 
@@ -603,6 +609,13 @@ class CreateRouter(command.ShowOne, comm
             )
             raise exceptions.CommandError(msg)
 
+        if parsed_args.qos_policy and not parsed_args.external_gateways:
+            msg = _(
+                "You must specify '--external-gateway' in order "
+                "to define a QoS policy"
+            )
+            raise exceptions.CommandError(msg)
+
         if parsed_args.enable_ndp_proxy is not None:
             attrs['enable_ndp_proxy'] = parsed_args.enable_ndp_proxy
 
@@ -671,7 +684,7 @@ class DeleteRouter(command.Command):
 
         if result > 0:
             total = len(parsed_args.router)
-            msg = _("%(result)s of %(total)s routers failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s routers failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -722,14 +735,14 @@ class ListRouter(command.Lister):
         identity_client = self.app.client_manager.identity
         client = self.app.client_manager.network
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             'status',
             'is_admin_state_up',
             'project_id',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Name',
             'Status',
@@ -775,27 +788,27 @@ class ListRouter(command.Lister):
                 d.is_distributed is not None
                 and 'is_distributed' not in columns
             ):
-                columns = columns + ('is_distributed',)
-                column_headers = column_headers + ('Distributed',)
+                columns += ('is_distributed',)
+                column_headers += ('Distributed',)
             if d.is_ha is not None and 'is_ha' not in columns:
-                columns = columns + ('is_ha',)
-                column_headers = column_headers + ('HA',)
+                columns += ('is_ha',)
+                column_headers += ('HA',)
         if parsed_args.long:
-            columns = columns + (
+            columns += (
                 'routes',
                 'external_gateway_info',
             )
-            column_headers = column_headers + (
+            column_headers += (
                 'Routes',
                 'External gateway info',
             )
             # availability zone will be available only when
             # router_availability_zone extension is enabled
             if client.find_extension("router_availability_zone"):
-                columns = columns + ('availability_zones',)
-                column_headers = column_headers + ('Availability zones',)
-            columns = columns + ('tags',)
-            column_headers = column_headers + ('Tags',)
+                columns += ('availability_zones',)
+                column_headers += ('Availability zones',)
+            columns += ('tags',)
+            column_headers += ('Tags',)
 
         return (
             column_headers,
@@ -927,7 +940,7 @@ class SetRouter(common.NeutronCommandWit
             default=None,
             required_keys=['destination', 'gateway'],
             help=_(
-                "Add routes to the router "
+                "Add routes to the router. "
                 "destination: destination subnet (in CIDR notation) "
                 "gateway: nexthop IP address "
                 "(repeat option to add multiple routes). "
@@ -951,7 +964,7 @@ class SetRouter(common.NeutronCommandWit
             '--ha',
             action='store_true',
             help=_(
-                "Set the router as highly available " "(disabled router only)"
+                "Set the router as highly available (disabled router only)"
             ),
         )
         routes_ha.add_argument(
@@ -967,7 +980,7 @@ class SetRouter(common.NeutronCommandWit
             metavar="<network>",
             action='append',
             help=_(
-                "External Network used as router's gateway (name or ID). "
+                "External Network used as router's gateway (name or ID) "
                 "(repeat option to set multiple gateways per router "
                 "if the L3 service plugin in use supports it)."
             ),
@@ -983,7 +996,7 @@ class SetRouter(common.NeutronCommandWit
                 "Desired IP and/or subnet (name or ID) "
                 "on external gateway: "
                 "subnet=<subnet>,ip-address=<ip-address> "
-                "(repeat option to set multiple fixed IP addresses)."
+                "(repeat option to set multiple fixed IP addresses)"
             ),
         )
         snat_group = parser.add_mutually_exclusive_group()
@@ -1163,7 +1176,7 @@ class UnsetRouter(common.NeutronUnsetCom
             default=None,
             required_keys=['destination', 'gateway'],
             help=_(
-                "Routes to be removed from the router "
+                "Routes to be removed from the router. "
                 "destination: destination subnet (in CIDR notation) "
                 "gateway: nexthop IP address "
                 "(repeat option to unset multiple routes)"
@@ -1216,7 +1229,7 @@ class UnsetRouter(common.NeutronUnsetCom
                 ):
                     pass
             except (KeyError, TypeError):
-                msg = _("Router does not have external network or qos policy")
+                msg = _("Router does not have external network or QoS policy")
                 raise exceptions.CommandError(msg)
             else:
                 attrs['external_gateway_info'] = {
@@ -1253,13 +1266,12 @@ class AddGatewayToRouter(command.ShowOne
         parser.add_argument(
             'router',
             metavar="<router>",
-            help=_("Router to modify (name or ID)."),
+            help=_("Router to modify (name or ID)"),
         )
         parser.add_argument(
             metavar="<network>",
             help=_(
-                "External Network to a attach a router gateway to (name or "
-                "ID)."
+                "External Network to a attach a router gateway to (name or ID)"
             ),
             dest='external_gateways',
             # The argument is stored in a list in order to reuse the
@@ -1276,7 +1288,7 @@ class AddGatewayToRouter(command.ShowOne
                 "Desired IP and/or subnet (name or ID) "
                 "on external gateway: "
                 "subnet=<subnet>,ip-address=<ip-address> "
-                "(repeat option to set multiple fixed IP addresses)."
+                "(repeat option to set multiple fixed IP addresses)"
             ),
         )
         return parser
@@ -1326,8 +1338,7 @@ class RemoveGatewayFromRouter(command.Sh
         parser.add_argument(
             metavar="<network>",
             help=_(
-                "External Network to remove a router gateway from (name or "
-                "ID)."
+                "External Network to remove a router gateway from (name or ID)"
             ),
             dest='external_gateways',
             # The argument is stored in a list in order to reuse the
@@ -1344,7 +1355,7 @@ class RemoveGatewayFromRouter(command.Sh
                 "IP and/or subnet (name or ID) on the external gateway "
                 "which is used to identify a particular gateway if multiple "
                 "are attached to the same network: subnet=<subnet>,"
-                "ip-address=<ip-address>."
+                "ip-address=<ip-address>"
             ),
         )
         return parser
diff -pruN 7.4.0-3/openstackclient/network/v2/security_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/security_group.py
--- 7.4.0-3/openstackclient/network/v2/security_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/security_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -89,9 +89,11 @@ def _get_columns(item):
     # We still support Nova managed security groups, where we have tenant_id.
     column_map = {
         'security_group_rules': 'rules',
-        'tenant_id': 'project_id',
     }
-    hidden_columns = ['location']
+    # FIXME(lajoskatona): Stop hiding is_shared when
+    # https://review.opendev.org/c/openstack/openstacksdk/+/950305
+    # is released and SDK version is bumped
+    hidden_columns = ['location', 'tenant_id', 'is_shared']
     return utils.get_osc_show_columns_for_sdk_resource(
         item, column_map, hidden_columns
     )
@@ -126,7 +128,7 @@ class CreateSecurityGroup(
             "--stateful",
             action='store_true',
             default=None,
-            help=_("Security group is stateful (Default)"),
+            help=_("Security group is stateful (default)"),
         )
         stateful_group.add_argument(
             "--stateless",
@@ -186,7 +188,8 @@ class CreateSecurityGroup(
             parsed_args.name,
             description,
         )
-        display_columns, property_columns = _get_columns(obj)
+        display_columns = ('description', 'id', 'name', 'project_id', 'rules')
+        property_columns = ('description', 'id', 'name', 'tenant_id', 'rules')
         data = utils.get_dict_properties(
             obj, property_columns, formatters=_formatters_compute
         )
@@ -239,10 +242,7 @@ class ListSecurityGroup(common.NetworkAn
             '--project',
             metavar='<project>',
             help=self.enhance_help_neutron(
-                _(
-                    "List security groups according to the project (name or "
-                    "ID)"
-                )
+                _("List security groups according to the project (name or ID)")
             ),
         )
         identity_common.add_project_domain_option_to_parser(
@@ -280,7 +280,7 @@ class ListSecurityGroup(common.NetworkAn
             fields=self.FIELDS_TO_RETRIEVE, **filters
         )
 
-        columns = ("ID", "Name", "Description", "Project ID", "tags")
+        columns = ("id", "name", "description", "project_id", "tags")
         column_headers = ("ID", "Name", "Description", "Project", "Tags")
         return (
             column_headers,
@@ -300,15 +300,11 @@ class ListSecurityGroup(common.NetworkAn
             all_projects=parsed_args.all_projects,
         )
 
-        columns = (
-            "ID",
-            "Name",
-            "Description",
-        )
-        column_headers = columns
+        columns: tuple[str, ...] = ("id", "name", "description")
+        column_headers: tuple[str, ...] = ("ID", "Name", "Description")
         if parsed_args.all_projects:
-            columns = columns + ('Tenant ID',)
-            column_headers = column_headers + ('Project',)
+            columns += ('tenant_id',)
+            column_headers += ('Project',)
         return (
             column_headers,
             (
@@ -345,7 +341,7 @@ class SetSecurityGroup(
             "--stateful",
             action='store_true',
             default=None,
-            help=_("Security group is stateful (Default)"),
+            help=_("Security group is stateful (default)"),
         )
         stateful_group.add_argument(
             "--stateless",
@@ -427,7 +423,8 @@ class ShowSecurityGroup(common.NetworkAn
 
     def take_action_compute(self, client, parsed_args):
         obj = compute_v2.find_security_group(client, parsed_args.group)
-        display_columns, property_columns = _get_columns(obj)
+        display_columns = ('description', 'id', 'name', 'project_id', 'rules')
+        property_columns = ('description', 'id', 'name', 'tenant_id', 'rules')
         data = utils.get_dict_properties(
             obj, property_columns, formatters=_formatters_compute
         )
diff -pruN 7.4.0-3/openstackclient/network/v2/security_group_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/security_group_rule.py
--- 7.4.0-3/openstackclient/network/v2/security_group_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/security_group_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -30,10 +30,9 @@ LOG = logging.getLogger(__name__)
 
 
 def _get_columns(item):
-    column_map = {}
-    hidden_columns = ['location', 'tenant_id']
+    hidden_columns = ['location', 'name', 'tenant_id', 'tags']
     return utils.get_osc_show_columns_for_sdk_resource(
-        item, column_map, hidden_columns
+        item, {}, hidden_columns
     )
 
 
@@ -451,7 +450,7 @@ class ListSecurityGroupRule(common.Netwo
         return parser
 
     def _get_column_headers(self, parsed_args):
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'IP Protocol',
             'Ethertype',
@@ -461,9 +460,9 @@ class ListSecurityGroupRule(common.Netwo
             'Remote Security Group',
         )
         if self.is_neutron:
-            column_headers = column_headers + ('Remote Address Group',)
+            column_headers += ('Remote Address Group',)
         if parsed_args.group is None:
-            column_headers = column_headers + ('Security Group',)
+            column_headers += ('Security Group',)
         return column_headers
 
     def take_action_network(self, client, parsed_args):
@@ -474,7 +473,7 @@ class ListSecurityGroupRule(common.Netwo
             self.log.warning(msg)
 
         column_headers = self._get_column_headers(parsed_args)
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'protocol',
             'ether_type',
@@ -496,7 +495,7 @@ class ListSecurityGroupRule(common.Netwo
             ).id
             query = {'security_group_id': security_group_id}
         else:
-            columns = columns + ('security_group_id',)
+            columns += ('security_group_id',)
 
         if parsed_args.ingress:
             query['direction'] = 'ingress'
@@ -523,7 +522,7 @@ class ListSecurityGroupRule(common.Netwo
 
     def take_action_compute(self, client, parsed_args):
         column_headers = self._get_column_headers(parsed_args)
-        columns = (
+        columns: tuple[str, ...] = (
             "ID",
             "IP Protocol",
             "Ethertype",
@@ -539,7 +538,7 @@ class ListSecurityGroupRule(common.Netwo
             )
             rules_to_list = security_group['rules']
         else:
-            columns = columns + ('parent_group_id',)
+            columns += ('parent_group_id',)
             for security_group in compute_v2.list_security_groups(
                 client, all_projects=parsed_args.all_projects
             ):
@@ -608,7 +607,7 @@ class ShowSecurityGroupRule(common.Netwo
 
         if obj is None:
             msg = (
-                _("Could not find security group rule " "with ID '%s'")
+                _("Could not find security group rule with ID '%s'")
                 % parsed_args.rule
             )
             raise exceptions.CommandError(msg)
diff -pruN 7.4.0-3/openstackclient/network/v2/subnet.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/subnet.py
--- 7.4.0-3/openstackclient/network/v2/subnet.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/subnet.py	2025-07-07 22:41:56.000000000 +0000
@@ -15,6 +15,7 @@
 
 import copy
 import logging
+import typing as ty
 
 from cliff import columns as cliff_columns
 from osc_lib.cli import format_columns
@@ -84,8 +85,8 @@ def _get_common_parse_arguments(parser,
         action=parseractions.MultiKeyValueAction,
         required_keys=['start', 'end'],
         help=_(
-            "Allocation pool IP addresses for this subnet "
-            "e.g.: start=192.168.199.2,end=192.168.199.254 "
+            "Allocation pool IP addresses for this subnet, "
+            "for example, start=192.168.199.2,end=192.168.199.254 "
             "(repeat option to add multiple IP addresses)"
         ),
     )
@@ -127,10 +128,10 @@ def _get_common_parse_arguments(parser,
         action=parseractions.MultiKeyValueAction,
         required_keys=['destination', 'gateway'],
         help=_(
-            "Additional route for this subnet "
-            "e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 "
+            "Additional route for this subnet, "
+            "for example, destination=10.10.0.0/16,gateway=192.168.71.254 "
             "destination: destination subnet (in CIDR notation) "
-            "gateway: nexthop IP address "
+            "gateway: next-hop IP address "
             "(repeat option to add multiple routes)"
         ),
     )
@@ -150,8 +151,8 @@ def _get_common_parse_arguments(parser,
         action='append',
         dest='service_types',
         help=_(
-            "Service type for this subnet "
-            "e.g.: network:floatingip_agent_gateway. "
+            "Service type for this subnet, "
+            "for example, network:floatingip_agent_gateway. "
             "Must be a valid device owner value for a network port "
             "(repeat option to set multiple service types)"
         ),
@@ -365,8 +366,8 @@ class CreateSubnet(command.ShowOne, comm
                 "<ip-address>: Specific IP address to use as the gateway, "
                 "'auto': Gateway address should automatically be chosen "
                 "from within the subnet itself, 'none': This subnet will "
-                "not use a gateway, e.g.: --gateway 192.168.9.1, "
-                "--gateway auto, --gateway none (default is 'auto')."
+                "not use a gateway. For example, --gateway 192.168.9.1, "
+                "--gateway auto or --gateway none (default is 'auto')."
             ),
         )
         parser.add_argument(
@@ -375,7 +376,7 @@ class CreateSubnet(command.ShowOne, comm
             default=4,
             choices=[4, 6],
             help=_(
-                "IP version (default is 4).  Note that when subnet pool is "
+                "IP version (default is 4). Note that when subnet pool is "
                 "specified, IP version is determined from the subnet pool "
                 "and this option is ignored."
             ),
@@ -400,7 +401,7 @@ class CreateSubnet(command.ShowOne, comm
             '--network-segment',
             metavar='<network-segment>',
             help=_(
-                "Network segment to associate with this subnet " "(name or ID)"
+                "Network segment to associate with this subnet (name or ID)"
             ),
         )
         parser.add_argument(
@@ -465,7 +466,7 @@ class DeleteSubnet(command.Command):
 
         if result > 0:
             total = len(parsed_args.subnet)
-            msg = _("%(result)s of %(total)s subnets failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s subnets failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -513,10 +514,10 @@ class ListSubnet(command.Lister):
             action='append',
             dest='service_types',
             help=_(
-                "List only subnets of a given service type in output "
-                "e.g.: network:floatingip_agent_gateway. "
+                "List only subnets of a given service type in output, "
+                "for example, network:floatingip_agent_gateway. "
                 "Must be a valid device owner value for a network port "
-                "(repeat option to list multiple service types)"
+                "(repeat option to list multiple service types)."
             ),
         )
         parser.add_argument(
@@ -551,8 +552,8 @@ class ListSubnet(command.Lister):
             metavar='<subnet-range>',
             help=_(
                 "List only subnets of given subnet range "
-                "(in CIDR notation) in output "
-                "e.g.: --subnet-range 10.10.0.0/16"
+                "(in CIDR notation) in output. "
+                "For example, --subnet-range 10.10.0.0/16"
             ),
         )
         parser.add_argument(
@@ -560,7 +561,7 @@ class ListSubnet(command.Lister):
             metavar='<subnet-pool>',
             help=_(
                 "List only subnets which belong to a given subnet pool "
-                "in output (Name or ID)"
+                "in output (name or ID)"
             ),
         )
         _tag.add_tag_filtering_option_to_parser(parser, _('subnets'))
@@ -606,8 +607,8 @@ class ListSubnet(command.Lister):
         _tag.get_tag_filtering_args(parsed_args, filters)
         data = network_client.subnets(**filters)
 
-        headers = ('ID', 'Name', 'Network', 'Subnet')
-        columns = ('id', 'name', 'network_id', 'cidr')
+        headers: tuple[str, ...] = ('ID', 'Name', 'Network', 'Subnet')
+        columns: tuple[str, ...] = ('id', 'name', 'network_id', 'cidr')
         if parsed_args.long:
             headers += (
                 'Project',
@@ -684,8 +685,8 @@ class SetSubnet(common.NeutronCommandWit
             help=_(
                 "Specify a gateway for the subnet. The options are: "
                 "<ip-address>: Specific IP address to use as the gateway, "
-                "'none': This subnet will not use a gateway, "
-                "e.g.: --gateway 192.168.9.1, --gateway none."
+                "'none': This subnet will not use a gateway. "
+                "For example, --gateway 192.168.9.1 or --gateway none."
             ),
         )
         parser.add_argument(
@@ -694,7 +695,7 @@ class SetSubnet(common.NeutronCommandWit
             help=_(
                 "Network segment to associate with this subnet (name or "
                 "ID). It is only allowed to set the segment if the current "
-                "value is `None`, the network must also have only one "
+                "value is `None`. The network must also have only one "
                 "segment and only one subnet can exist on the network."
             ),
         )
@@ -774,7 +775,7 @@ class UnsetSubnet(common.NeutronUnsetCom
             required_keys=['start', 'end'],
             help=_(
                 'Allocation pool IP addresses to be removed from this '
-                'subnet e.g.: start=192.168.199.2,end=192.168.199.254 '
+                'subnet, for example, start=192.168.199.2,end=192.168.199.254 '
                 '(repeat option to unset multiple allocation pools)'
             ),
         )
@@ -800,10 +801,10 @@ class UnsetSubnet(common.NeutronUnsetCom
             action=parseractions.MultiKeyValueAction,
             required_keys=['destination', 'gateway'],
             help=_(
-                'Route to be removed from this subnet '
-                'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
+                'Route to be removed from this subnet, '
+                'for example, destination=10.10.0.0/16,gateway=192.168.71.254 '
                 'destination: destination subnet (in CIDR notation) '
-                'gateway: nexthop IP address '
+                'gateway: next-hop IP address '
                 '(repeat option to unset multiple host routes)'
             ),
         )
@@ -813,8 +814,8 @@ class UnsetSubnet(common.NeutronUnsetCom
             action='append',
             dest='service_types',
             help=_(
-                'Service type to be removed from this subnet '
-                'e.g.: network:floatingip_agent_gateway. '
+                'Service type to be removed from this subnet, '
+                'for example, network:floatingip_agent_gateway. '
                 'Must be a valid device owner value for a network port '
                 '(repeat option to unset multiple service types)'
             ),
@@ -831,7 +832,7 @@ class UnsetSubnet(common.NeutronUnsetCom
         client = self.app.client_manager.network
         obj = client.find_subnet(parsed_args.subnet, ignore_missing=False)
 
-        attrs = {}
+        attrs: dict[str, ty.Any] = {}
         if parsed_args.gateway:
             attrs['gateway_ip'] = None
         if parsed_args.dns_nameservers:
diff -pruN 7.4.0-3/openstackclient/network/v2/subnet_pool.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/subnet_pool.py
--- 7.4.0-3/openstackclient/network/v2/subnet_pool.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/network/v2/subnet_pool.py	2025-07-07 22:41:56.000000000 +0000
@@ -256,7 +256,7 @@ class DeleteSubnetPool(command.Command):
         if result > 0:
             total = len(parsed_args.subnet_pool)
             msg = _(
-                "%(result)s of %(total)s subnet pools failed " "to delete."
+                "%(result)s of %(total)s subnet pools failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -290,7 +290,7 @@ class ListSubnetPool(command.Lister):
             '--default',
             action='store_true',
             help=_(
-                "List subnet pools used as the default external " "subnet pool"
+                "List subnet pools used as the default external subnet pool"
             ),
         )
         default_group.add_argument(
@@ -356,8 +356,8 @@ class ListSubnetPool(command.Lister):
         _tag.get_tag_filtering_args(parsed_args, filters)
         data = network_client.subnet_pools(**filters)
 
-        headers = ('ID', 'Name', 'Prefixes')
-        columns = ('id', 'name', 'prefixes')
+        headers: tuple[str, ...] = ('ID', 'Name', 'Prefixes')
+        columns: tuple[str, ...] = ('id', 'name', 'prefixes')
         if parsed_args.long:
             headers += (
                 'Default Prefix Length',
diff -pruN 7.4.0-3/openstackclient/object/client.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/object/client.py
--- 7.4.0-3/openstackclient/object/client.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/object/client.py	2025-07-07 22:41:56.000000000 +0000
@@ -19,12 +19,11 @@ from osc_lib import utils
 
 from openstackclient.api import object_store_v1
 
+# global variables used when building the shell
 DEFAULT_API_VERSION = '1'
 API_VERSION_OPTION = 'os_object_api_version'
 API_NAME = 'object_store'
-API_VERSIONS = {
-    '1': 'openstackclient.object.client.ObjectClientv1',
-}
+API_VERSIONS = ('1',)
 
 
 def make_client(instance):
diff -pruN 7.4.0-3/openstackclient/object/v1/container.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/object/v1/container.py
--- 7.4.0-3/openstackclient/object/v1/container.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/object/v1/container.py	2025-07-07 22:41:56.000000000 +0000
@@ -148,10 +148,9 @@ class ListContainer(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('Name',)
         if parsed_args.long:
-            columns = ('Name', 'Bytes', 'Count')
-        else:
-            columns = ('Name',)
+            columns += ('Bytes', 'Count')
 
         kwargs = {}
         if parsed_args.prefix:
diff -pruN 7.4.0-3/openstackclient/object/v1/object.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/object/v1/object.py
--- 7.4.0-3/openstackclient/object/v1/object.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/object/v1/object.py	2025-07-07 22:41:56.000000000 +0000
@@ -162,16 +162,9 @@ class ListObject(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
+        columns: tuple[str, ...] = ('Name',)
         if parsed_args.long:
-            columns = (
-                'Name',
-                'Bytes',
-                'Hash',
-                'Content Type',
-                'Last Modified',
-            )
-        else:
-            columns = ('Name',)
+            columns += ('Bytes', 'Hash', 'Content Type', 'Last Modified')
 
         kwargs = {}
         if parsed_args.prefix:
diff -pruN 7.4.0-3/openstackclient/shell.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/shell.py
--- 7.4.0-3/openstackclient/shell.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/shell.py	2025-07-07 22:41:56.000000000 +0000
@@ -88,17 +88,34 @@ class OpenStackShell(shell.OpenStackShel
                     # this throws an exception if invalid
                     skip_old_check = mod_check_api_version(version_opt)
 
+                # NOTE(stephenfin): API_VERSIONS has traditionally been a
+                # dictionary but the values are only used internally and are
+                # ignored for the modules using SDK. So we now support tuples
+                # instead.
                 mod_versions = getattr(mod, 'API_VERSIONS', None)
-                if not skip_old_check and mod_versions:
+                if mod_versions is not None and not isinstance(
+                    mod_versions, dict | tuple
+                ):
+                    raise TypeError(
+                        f'Plugin {mod} has incompatible API_VERSIONS. '
+                        f'Expected: tuple, dict. Got: {type(mod_versions)}. '
+                        f'Please report this to your package maintainer.'
+                    )
+
+                if mod_versions and not skip_old_check:
                     if version_opt not in mod_versions:
                         sorted_versions = sorted(
-                            mod.API_VERSIONS.keys(),
+                            list(mod.API_VERSIONS),
                             key=lambda s: list(map(int, s.split('.'))),
                         )
                         self.log.warning(
-                            "{} version {} is not in supported versions: {}".format(
-                                api, version_opt, ', '.join(sorted_versions)
-                            )
+                            "%(name)s API version %(version)s is not in "
+                            "supported versions: %(supported)s",
+                            {
+                                'name': api,
+                                'version': version_opt,
+                                'supported': ', '.join(sorted_versions),
+                            },
                         )
 
                 # Command groups deal only with major versions
diff -pruN 7.4.0-3/openstackclient/tests/functional/base.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/base.py
--- 7.4.0-3/openstackclient/tests/functional/base.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/base.py	2025-07-07 22:41:56.000000000 +0000
@@ -36,8 +36,8 @@ def execute(cmd, *, fail_ok=False):
 
     proc = subprocess.Popen(cmdlist, stdout=stdout, stderr=stderr, env=env)
 
-    result_out, result_err = proc.communicate()
-    result_out = result_out.decode('utf-8')
+    result_out_b, result_err = proc.communicate()
+    result_out = result_out_b.decode('utf-8')
     LOG.debug('stdout: %s', result_out)
     LOG.debug('stderr: %s', result_err)
 
@@ -97,7 +97,11 @@ class TestCase(testtools.TestCase):
         )
 
         if parse_output:
-            return json.loads(output)
+            try:
+                return json.loads(output)
+            except json.JSONDecodeError:
+                print(f'failed to decode: {output}')
+                raise
         else:
             return output
 
diff -pruN 7.4.0-3/openstackclient/tests/functional/common/test_quota.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/common/test_quota.py
--- 7.4.0-3/openstackclient/tests/functional/common/test_quota.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/common/test_quota.py	2025-07-07 22:41:56.000000000 +0000
@@ -25,7 +25,7 @@ class QuotaTests(base.TestCase):
     test runs as these may run in parallel and otherwise step on each other.
     """
 
-    PROJECT_NAME = None
+    PROJECT_NAME: str
 
     @classmethod
     def setUpClass(cls):
@@ -250,6 +250,8 @@ class QuotaTests(base.TestCase):
             row_headers = [str(r) for r in row.keys()]
             self.assertEqual(sorted(expected_headers), sorted(row_headers))
             resources.append(row['Resource'])
+            for header in expected_headers[1:]:
+                self.assertIsInstance(row[header], int)
         # Ensure that returned quota has network quota...
         self.assertIn("networks", resources)
         # ...and compute quota
diff -pruN 7.4.0-3/openstackclient/tests/functional/compute/v2/common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/common.py
--- 7.4.0-3/openstackclient/tests/functional/compute/v2/common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/common.py	2025-07-07 22:41:56.000000000 +0000
@@ -22,9 +22,9 @@ from openstackclient.tests.functional im
 class ComputeTestCase(base.TestCase):
     """Common functional test bits for Compute commands"""
 
-    flavor_name = None
-    image_name = None
-    network_arg = None
+    flavor_name: str
+    image_name: str
+    network_arg: str
 
     def setUp(self):
         """Select common resources"""
@@ -34,7 +34,7 @@ class ComputeTestCase(base.TestCase):
         self.network_arg = self.get_network()
 
     @classmethod
-    def get_flavor(cls):
+    def get_flavor(cls) -> str:
         # NOTE(rtheis): Get cirros256 or m1.tiny flavors since functional
         #               tests may create other flavors.
         flavors = cls.openstack("flavor list", parse_output=True)
@@ -43,10 +43,13 @@ class ComputeTestCase(base.TestCase):
             if flavor['Name'] in ['m1.tiny', 'cirros256']:
                 server_flavor = flavor['Name']
                 break
+
+        assert server_flavor is not None
+
         return server_flavor
 
     @classmethod
-    def get_image(cls):
+    def get_image(cls) -> str:
         # NOTE(rtheis): Get first Cirros image since functional tests may
         #               create other images.  Image may be named '-uec' or
         #               '-disk'.
@@ -59,10 +62,13 @@ class ComputeTestCase(base.TestCase):
             ):
                 server_image = image['Name']
                 break
+
+        assert server_image is not None
+
         return server_image
 
     @classmethod
-    def get_network(cls):
+    def get_network(cls) -> str:
         try:
             # NOTE(rtheis): Get private network since functional tests may
             #               create other networks.
diff -pruN 7.4.0-3/openstackclient/tests/functional/compute/v2/test_keypair.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/test_keypair.py
--- 7.4.0-3/openstackclient/tests/functional/compute/v2/test_keypair.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/test_keypair.py	2025-07-07 22:41:56.000000000 +0000
@@ -21,12 +21,18 @@ from openstackclient.tests.functional im
 class KeypairBase(base.TestCase):
     """Methods for functional tests."""
 
-    def keypair_create(self, name=data_utils.rand_uuid()):
+    def keypair_create(self, name=data_utils.rand_uuid(), user=None):
         """Create keypair and add cleanup."""
-        raw_output = self.openstack('keypair create ' + name)
-        self.addCleanup(self.keypair_delete, name, True)
+        cmd = 'keypair create ' + name
+        if user is not None:
+            cmd += ' --user ' + user
+        raw_output = self.openstack(cmd)
+        self.addCleanup(
+            self.keypair_delete, name, ignore_exceptions=True, user=user
+        )
         if not raw_output:
             self.fail('Keypair has not been created!')
+        return name
 
     def keypair_list(self, params=''):
         """Return dictionary with list of keypairs."""
@@ -34,10 +40,13 @@ class KeypairBase(base.TestCase):
         keypairs = self.parse_show_as_object(raw_output)
         return keypairs
 
-    def keypair_delete(self, name, ignore_exceptions=False):
+    def keypair_delete(self, name, ignore_exceptions=False, user=None):
         """Try to delete keypair by name."""
         try:
-            self.openstack('keypair delete ' + name)
+            cmd = 'keypair delete ' + name
+            if user is not None:
+                cmd += ' --user ' + user
+            self.openstack(cmd)
         except exceptions.CommandFailed:
             if not ignore_exceptions:
                 raise
@@ -200,3 +209,30 @@ class KeypairTests(KeypairBase):
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, HEADERS)
         self.assertInOutput(self.KPName, raw_output)
+
+    def test_keypair_list_by_project(self):
+        """Test keypair list by project.
+
+        Test steps:
+        1) Create keypair for admin project in setUp
+        2) Create a new project
+        3) Create a new user
+        4) Associate the new user with the new project
+        5) Create keypair for the new user
+        6) List keypairs by the new project
+        7) Check that only the keypair from step 5 is returned
+        """
+        project_name = data_utils.rand_name('TestProject')
+        self.openstack(f'project create {project_name}')
+        self.addCleanup(self.openstack, f'project delete {project_name}')
+        user_name = data_utils.rand_name('TestUser')
+        self.openstack(f'user create {user_name}')
+        self.addCleanup(self.openstack, f'user delete {user_name}')
+        self.openstack(
+            f'role add --user {user_name} --project {project_name} member'
+        )
+        keypair_name = self.keypair_create(user=user_name)
+        raw_output = self.openstack(f'keypair list --project {project_name}')
+        items = self.parse_listing(raw_output)
+        self.assertEqual(1, len(items))
+        self.assertEqual(keypair_name, items[0]['Name'])
diff -pruN 7.4.0-3/openstackclient/tests/functional/compute/v2/test_server.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/test_server.py
--- 7.4.0-3/openstackclient/tests/functional/compute/v2/test_server.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/test_server.py	2025-07-07 22:41:56.000000000 +0000
@@ -156,7 +156,7 @@ class ServerTests(common.ComputeTestCase
         server_name3 = cmd_output['name']
 
         cmd_output = self.openstack(
-            'server list ' '--changes-since ' + updated_at2,
+            'server list --changes-since ' + updated_at2,
             parse_output=True,
         )
 
@@ -852,8 +852,7 @@ class ServerTests(common.ComputeTestCase
             # it to the server at /dev/vdb and delete the volume when the
             # server is deleted.
             bdm_arg = (
-                f'--block-device-mapping '
-                f'vdb={self.image_name}:image:1:true '
+                f'--block-device-mapping vdb={self.image_name}:image:1:true '
             )
         else:
             # get image ID
diff -pruN 7.4.0-3/openstackclient/tests/functional/compute/v2/test_server_event.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/test_server_event.py
--- 7.4.0-3/openstackclient/tests/functional/compute/v2/test_server_event.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/compute/v2/test_server_event.py	2025-07-07 22:41:56.000000000 +0000
@@ -93,7 +93,7 @@ class ServerEventTests(common.ComputeTes
         # And verify we can get the event list after it's deleted
         # Test 'server event list' for deleting
         cmd_output = self.openstack(
-            '--os-compute-api-version 2.21 ' 'server event list ' + server_id,
+            '--os-compute-api-version 2.21 server event list ' + server_id,
             parse_output=True,
         )
         request_id = None
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v2/test_user.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v2/test_user.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v2/test_user.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v2/test_user.py	2025-07-07 22:41:56.000000000 +0000
@@ -37,7 +37,7 @@ class UserTests(common.IdentityTests):
         new_username = data_utils.rand_name('NewTestUser')
         new_email = data_utils.rand_name() + '@example.com'
         raw_output = self.openstack(
-            'user set ' '--email {email} ' '--name {new_name} ' '{id}'.format(
+            'user set --email {email} --name {new_name} {id}'.format(
                 email=new_email, new_name=new_username, id=user['id']
             )
         )
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/common.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/common.py	2025-07-07 22:41:56.000000000 +0000
@@ -187,8 +187,7 @@ class IdentityTests(base.TestCase):
                 f'domain set --disable {cls.domain_name}'
             )
             cls.openstack(
-                '--os-identity-api-version 3 '
-                f'domain delete {cls.domain_name}'
+                f'--os-identity-api-version 3 domain delete {cls.domain_name}'
             )
         finally:
             super().tearDownClass()
@@ -270,9 +269,7 @@ class IdentityTests(base.TestCase):
         if add_clean_up:
             self.addCleanup(
                 self.openstack,
-                'group delete '
-                f'--domain {self.domain_name} '
-                f'{group_name}',
+                f'group delete --domain {self.domain_name} {group_name}',
             )
         items = self.parse_show(raw_output)
         self.assert_show_fields(items, self.GROUP_FIELDS)
@@ -305,9 +302,7 @@ class IdentityTests(base.TestCase):
         if add_clean_up:
             self.addCleanup(
                 self.openstack,
-                'project delete '
-                f'--domain {self.domain_name} '
-                f'{project_name}',
+                f'project delete --domain {self.domain_name} {project_name}',
             )
         return project_name
 
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_access_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_access_rule.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_access_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_access_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -62,7 +62,7 @@ class AccessRuleTests(common.IdentityTes
 
         items = self.parse_show_as_object(raw_output)
         self.access_rule_ids = [
-            x['id'] for x in ast.literal_eval(items['access_rules'])
+            x['id'] for x in ast.literal_eval(items['Access Rules'])
         ]
         self.addCleanup(
             self.openstack,
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_application_credential.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_application_credential.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_application_credential.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_application_credential.py	2025-07-07 22:41:56.000000000 +0000
@@ -21,13 +21,13 @@ from openstackclient.tests.functional.id
 
 class ApplicationCredentialTests(common.IdentityTests):
     APPLICATION_CREDENTIAL_FIELDS = [
-        'id',
-        'name',
-        'project_id',
-        'description',
-        'roles',
-        'expires_at',
-        'unrestricted',
+        'ID',
+        'Name',
+        'Project ID',
+        'Description',
+        'Roles',
+        'Expires At',
+        'Unrestricted',
     ]
     APPLICATION_CREDENTIAL_LIST_HEADERS = [
         'ID',
@@ -50,35 +50,35 @@ class ApplicationCredentialTests(common.
     def _create_role_assignments(self):
         try:
             user = self.openstack(
-                'configuration show -f value' ' -c auth.username'
+                'configuration show -f value -c auth.username'
             )
         except Exception:
             user = self.openstack(
-                'configuration show -f value' ' -c auth.user_id'
+                'configuration show -f value -c auth.user_id'
             )
         try:
             user_domain = self.openstack(
-                'configuration show -f value' ' -c auth.user_domain_name'
+                'configuration show -f value -c auth.user_domain_name'
             )
         except Exception:
             user_domain = self.openstack(
-                'configuration show -f value' ' -c auth.user_domain_id'
+                'configuration show -f value -c auth.user_domain_id'
             )
         try:
             project = self.openstack(
-                'configuration show -f value' ' -c auth.project_name'
+                'configuration show -f value -c auth.project_name'
             )
         except Exception:
             project = self.openstack(
-                'configuration show -f value' ' -c auth.project_id'
+                'configuration show -f value -c auth.project_id'
             )
         try:
             project_domain = self.openstack(
-                'configuration show -f value' ' -c auth.project_domain_name'
+                'configuration show -f value -c auth.project_domain_name'
             )
         except Exception:
             project_domain = self.openstack(
-                'configuration show -f value' ' -c auth.project_domain_id'
+                'configuration show -f value -c auth.project_domain_id'
             )
         role1 = self._create_dummy_role()
         role2 = self._create_dummy_role()
@@ -130,7 +130,7 @@ class ApplicationCredentialTests(common.
     def test_application_credential_delete(self):
         name = data_utils.rand_name('name')
         self.openstack(f'application credential create {name}')
-        raw_output = self.openstack('application credential delete ' f'{name}')
+        raw_output = self.openstack(f'application credential delete {name}')
         self.assertEqual(0, len(raw_output))
 
     def test_application_credential_list(self):
@@ -147,6 +147,6 @@ class ApplicationCredentialTests(common.
             self.openstack,
             f'application credential delete {name}',
         )
-        raw_output = self.openstack('application credential show ' f'{name}')
+        raw_output = self.openstack(f'application credential show {name}')
         items = self.parse_show(raw_output)
         self.assert_show_fields(items, self.APPLICATION_CREDENTIAL_FIELDS)
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_endpoint.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_endpoint.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_endpoint.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_endpoint.py	2025-07-07 22:41:56.000000000 +0000
@@ -45,7 +45,7 @@ class EndpointTests(common.IdentityTests
         endpoint_id = self._create_dummy_endpoint(add_clean_up=False)
         project_id = self._create_dummy_project(add_clean_up=False)
         raw_output = self.openstack(
-            'endpoint add project ' f'{endpoint_id} ' f'{project_id}'
+            f'endpoint add project {endpoint_id} {project_id}'
         )
         self.assertEqual(0, len(raw_output))
         raw_output = self.openstack(f'endpoint list --endpoint {endpoint_id}')
@@ -89,11 +89,11 @@ class EndpointTests(common.IdentityTests
         endpoint_id = self._create_dummy_endpoint(add_clean_up=False)
         project_id = self._create_dummy_project(add_clean_up=False)
         raw_output = self.openstack(
-            'endpoint add project ' f'{endpoint_id} ' f'{project_id}'
+            f'endpoint add project {endpoint_id} {project_id}'
         )
         self.assertEqual(0, len(raw_output))
 
         raw_output = self.openstack(
-            'endpoint remove project ' f'{endpoint_id} ' f'{project_id}'
+            f'endpoint remove project {endpoint_id} {project_id}'
         )
         self.assertEqual(0, len(raw_output))
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_group.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -36,14 +36,14 @@ class GroupTests(common.IdentityTests):
     def test_group_delete(self):
         group_name = self._create_dummy_group(add_clean_up=False)
         raw_output = self.openstack(
-            'group delete ' f'--domain {self.domain_name} ' f'{group_name}'
+            f'group delete --domain {self.domain_name} {group_name}'
         )
         self.assertEqual(0, len(raw_output))
 
     def test_group_show(self):
         group_name = self._create_dummy_group()
         raw_output = self.openstack(
-            'group show ' f'--domain {self.domain_name} ' f'{group_name}'
+            f'group show --domain {self.domain_name} {group_name}'
         )
         items = self.parse_show(raw_output)
         self.assert_show_fields(items, self.GROUP_FIELDS)
@@ -59,7 +59,7 @@ class GroupTests(common.IdentityTests):
         )
         self.assertEqual(0, len(raw_output))
         raw_output = self.openstack(
-            'group show ' f'--domain {self.domain_name} ' f'{new_group_name}'
+            f'group show --domain {self.domain_name} {new_group_name}'
         )
         group = self.parse_show_as_object(raw_output)
         self.assertEqual(new_group_name, group['name'])
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_idp.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_idp.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_idp.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_idp.py	2025-07-07 22:41:56.000000000 +0000
@@ -54,13 +54,9 @@ class IdentityProviderTests(common.Ident
         identity_provider = self._create_dummy_idp(add_clean_up=True)
         new_remoteid = data_utils.rand_name('newRemoteId')
         raw_output = self.openstack(
-            'identity provider set '
-            '%(identity-provider)s '
-            '--remote-id %(remote-id)s '
-            % {
-                'identity-provider': identity_provider,
-                'remote-id': new_remoteid,
-            }
+            f'identity provider set '
+            f'{identity_provider} '
+            f'--remote-id {new_remoteid}'
         )
         self.assertEqual(0, len(raw_output))
         raw_output = self.openstack(
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_limit.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_limit.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_limit.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_limit.py	2025-07-07 22:41:56.000000000 +0000
@@ -174,7 +174,7 @@ class LimitTestCase(common.IdentityTests
         }
 
         raw_output = self.openstack(
-            'limit set' ' --description {description}' ' {limit_id}'.format(
+            'limit set --description {description} {limit_id}'.format(
                 **params
             ),
             cloud=SYSTEM_CLOUD,
@@ -188,9 +188,9 @@ class LimitTestCase(common.IdentityTests
         params = {'resource_limit': 5, 'limit_id': limit_id}
 
         raw_output = self.openstack(
-            'limit set'
-            ' --resource-limit {resource_limit}'
-            ' {limit_id}'.format(**params),
+            'limit set --resource-limit {resource_limit} {limit_id}'.format(
+                **params
+            ),
             cloud=SYSTEM_CLOUD,
         )
         items = self.parse_show(raw_output)
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_project.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_project.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_project.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_project.py	2025-07-07 22:41:56.000000000 +0000
@@ -30,9 +30,7 @@ class ProjectTests(common.IdentityTests)
         )
         self.addCleanup(
             self.openstack,
-            'project delete '
-            f'--domain {self.domain_name} '
-            f'{project_name}',
+            f'project delete --domain {self.domain_name} {project_name}',
         )
         items = self.parse_show(raw_output)
         show_fields = list(self.PROJECT_FIELDS)
@@ -45,7 +43,7 @@ class ProjectTests(common.IdentityTests)
     def test_project_delete(self):
         project_name = self._create_dummy_project(add_clean_up=False)
         raw_output = self.openstack(
-            'project delete ' f'--domain {self.domain_name} ' f'{project_name}'
+            f'project delete --domain {self.domain_name} {project_name}'
         )
         self.assertEqual(0, len(raw_output))
 
@@ -77,9 +75,7 @@ class ProjectTests(common.IdentityTests)
         self.assertEqual(0, len(raw_output))
         # check project details
         raw_output = self.openstack(
-            'project show '
-            f'--domain {self.domain_name} '
-            f'{new_project_name}'
+            f'project show --domain {self.domain_name} {new_project_name}'
         )
         items = self.parse_show(raw_output)
         fields = list(self.PROJECT_FIELDS)
@@ -91,17 +87,12 @@ class ProjectTests(common.IdentityTests)
         self.assertEqual('v0', project['k0'])
         # reset project to make sure it will be cleaned up
         self.openstack(
-            'project set '
-            f'--name {project_name} '
-            '--enable '
-            f'{new_project_name}'
+            f'project set --name {project_name} --enable {new_project_name}'
         )
 
     def test_project_show(self):
         raw_output = self.openstack(
-            'project show '
-            f'--domain {self.domain_name} '
-            f'{self.project_name}'
+            f'project show --domain {self.domain_name} {self.project_name}'
         )
         items = self.parse_show(raw_output)
         self.assert_show_fields(items, self.PROJECT_FIELDS)
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_region.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_region.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_region.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_region.py	2025-07-07 22:41:56.000000000 +0000
@@ -49,9 +49,7 @@ class RegionTests(common.IdentityTests):
         self.assertEqual(region_id, region['region'])
         # update parent-region
         raw_output = self.openstack(
-            'region set '
-            f'--parent-region {new_parent_region_id} '
-            f'{region_id}'
+            f'region set --parent-region {new_parent_region_id} {region_id}'
         )
         self.assertEqual(0, len(raw_output))
         # check updated region details
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_registered_limit.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_registered_limit.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_registered_limit.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_registered_limit.py	2025-07-07 22:41:56.000000000 +0000
@@ -25,7 +25,7 @@ class RegisteredLimitTestCase(common.Ide
 
     def test_registered_limit_create_with_service_id(self):
         service_name = self._create_dummy_service()
-        raw_output = self.openstack('service show' f' {service_name}')
+        raw_output = self.openstack(f'service show {service_name}')
         service_items = self.parse_show(raw_output)
         service_id = self._extract_value_from_items('id', service_items)
 
@@ -44,7 +44,7 @@ class RegisteredLimitTestCase(common.Ide
         registered_limit_id = self._extract_value_from_items('id', items)
         self.addCleanup(
             self.openstack,
-            'registered limit delete' f' {registered_limit_id}',
+            f'registered limit delete {registered_limit_id}',
             cloud=SYSTEM_CLOUD,
         )
 
@@ -178,7 +178,7 @@ class RegisteredLimitTestCase(common.Ide
             add_clean_up=False
         )
         raw_output = self.openstack(
-            'registered limit delete' f' {registered_limit_id}',
+            f'registered limit delete {registered_limit_id}',
             cloud=SYSTEM_CLOUD,
         )
         self.assertEqual(0, len(raw_output))
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_role.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_role.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_role.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_role.py	2025-07-07 22:41:56.000000000 +0000
@@ -23,7 +23,7 @@ class RoleTests(common.IdentityTests):
         role_name = data_utils.rand_name('TestRole')
         description = data_utils.rand_name('description')
         raw_output = self.openstack(
-            'role create ' f'--description {description} ' f'{role_name}'
+            f'role create --description {description} {role_name}'
         )
         role = self.parse_show_as_object(raw_output)
         self.addCleanup(self.openstack, 'role delete {}'.format(role['id']))
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_role_assignment.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_role_assignment.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_role_assignment.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_role_assignment.py	2025-07-07 22:41:56.000000000 +0000
@@ -24,35 +24,25 @@ class RoleAssignmentTests(common.Identit
         username = self._create_dummy_user()
         system = 'all'
         raw_output = self.openstack(
-            'role add '
-            f'--user {username} '
-            f'--system {system} '
-            f'{role_name}'
+            f'role add --user {username} --system {system} {role_name}'
         )
         self.addCleanup(
             self.openstack,
-            'role remove '
-            f'--user {username} '
-            f'--system  {system} '
-            f'{role_name}',
+            f'role remove --user {username} --system  {system} {role_name}',
         )
         self.assertEqual(0, len(raw_output))
 
-        raw_output = self.openstack(
-            'role assignment list ' f'--user {username} '
-        )
+        raw_output = self.openstack(f'role assignment list --user {username} ')
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
         raw_output = self.openstack(
-            'role assignment list ' f'--role {role_name} '
+            f'role assignment list --role {role_name} '
         )
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
-        raw_output = self.openstack(
-            'role assignment list ' f'--system {system} '
-        )
+        raw_output = self.openstack(f'role assignment list --system {system} ')
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
@@ -61,22 +51,14 @@ class RoleAssignmentTests(common.Identit
         group = self._create_dummy_group()
         system = 'all'
         raw_output = self.openstack(
-            'role add '
-            f'--group {group} '
-            f'--system {system} '
-            f'{role_name}'
+            f'role add --group {group} --system {system} {role_name}'
         )
         self.addCleanup(
             self.openstack,
-            'role remove '
-            f'--group {group} '
-            f'--system {system} '
-            f'{role_name}',
+            f'role remove --group {group} --system {system} {role_name}',
         )
         self.assertEqual(0, len(raw_output))
-        raw_output = self.openstack(
-            'role assignment list ' f'--group {group} '
-        )
+        raw_output = self.openstack(f'role assignment list --group {group} ')
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
@@ -98,7 +80,7 @@ class RoleAssignmentTests(common.Identit
         )
         self.assertEqual(0, len(raw_output))
         raw_output = self.openstack(
-            'role assignment list ' f'--domain {self.domain_name} '
+            f'role assignment list --domain {self.domain_name} '
         )
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
@@ -121,23 +103,23 @@ class RoleAssignmentTests(common.Identit
         )
         self.assertEqual(0, len(raw_output))
         raw_output = self.openstack(
-            'role assignment list ' f'--project {self.project_name} '
+            f'role assignment list --project {self.project_name} '
         )
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
     def test_role_assignment_list_effective(self):
-        raw_output = self.openstack('role assignment list ' '--effective')
+        raw_output = self.openstack('role assignment list --effective')
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
     def test_role_assignment_list_auth_user(self):
-        raw_output = self.openstack('role assignment list ' '--auth-user')
+        raw_output = self.openstack('role assignment list --auth-user')
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
     def test_role_assignment_list_auth_project(self):
-        raw_output = self.openstack('role assignment list ' '--auth-project')
+        raw_output = self.openstack('role assignment list --auth-project')
         items = self.parse_listing(raw_output)
         self.assert_table_structure(items, self.ROLE_ASSIGNMENT_LIST_HEADERS)
 
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_service_provider.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_service_provider.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_service_provider.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_service_provider.py	2025-07-07 22:41:56.000000000 +0000
@@ -52,13 +52,9 @@ class ServiceProviderTests(common.Identi
         service_provider = self._create_dummy_sp(add_clean_up=True)
         new_description = data_utils.rand_name('newDescription')
         raw_output = self.openstack(
-            'service provider set '
-            '%(service-provider)s '
-            '--description %(description)s '
-            % {
-                'service-provider': service_provider,
-                'description': new_description,
-            }
+            f'service provider set '
+            f'{service_provider} '
+            f'--description {new_description}'
         )
         updated_value = self.parse_show_as_object(raw_output)
         self.assertEqual(new_description, updated_value.get('description'))
diff -pruN 7.4.0-3/openstackclient/tests/functional/identity/v3/test_user.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_user.py
--- 7.4.0-3/openstackclient/tests/functional/identity/v3/test_user.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/identity/v3/test_user.py	2025-07-07 22:41:56.000000000 +0000
@@ -22,7 +22,7 @@ class UserTests(common.IdentityTests):
     def test_user_delete(self):
         username = self._create_dummy_user(add_clean_up=False)
         raw_output = self.openstack(
-            'user delete ' f'--domain {self.domain_name} ' f'{username}'
+            f'user delete --domain {self.domain_name} {username}'
         )
         self.assertEqual(0, len(raw_output))
 
@@ -34,19 +34,19 @@ class UserTests(common.IdentityTests):
     def test_user_set(self):
         username = self._create_dummy_user()
         raw_output = self.openstack(
-            'user show ' f'--domain {self.domain_name} ' f'{username}'
+            f'user show --domain {self.domain_name} {username}'
         )
         user = self.parse_show_as_object(raw_output)
         new_username = data_utils.rand_name('NewTestUser')
         new_email = data_utils.rand_name() + '@example.com'
         raw_output = self.openstack(
-            'user set ' '--email {email} ' '--name {new_name} ' '{id}'.format(
+            'user set --email {email} --name {new_name} {id}'.format(
                 email=new_email, new_name=new_username, id=user['id']
             )
         )
         self.assertEqual(0, len(raw_output))
         raw_output = self.openstack(
-            'user show ' f'--domain {self.domain_name} ' f'{new_username}'
+            f'user show --domain {self.domain_name} {new_username}'
         )
         updated_user = self.parse_show_as_object(raw_output)
         self.assertEqual(user['id'], updated_user['id'])
@@ -57,7 +57,7 @@ class UserTests(common.IdentityTests):
         project_name = self._create_dummy_project()
         # get original user details
         raw_output = self.openstack(
-            'user show ' f'--domain {self.domain_name} ' f'{username}'
+            f'user show --domain {self.domain_name} {username}'
         )
         user = self.parse_show_as_object(raw_output)
         # update user
@@ -74,12 +74,12 @@ class UserTests(common.IdentityTests):
         self.assertEqual(0, len(raw_output))
         # get updated user details
         raw_output = self.openstack(
-            'user show ' f'--domain {self.domain_name} ' f'{username}'
+            f'user show --domain {self.domain_name} {username}'
         )
         updated_user = self.parse_show_as_object(raw_output)
         # get project details
         raw_output = self.openstack(
-            'project show ' f'--domain {self.domain_name} ' f'{project_name}'
+            f'project show --domain {self.domain_name} {project_name}'
         )
         project = self.parse_show_as_object(raw_output)
         # check updated user details
@@ -89,7 +89,7 @@ class UserTests(common.IdentityTests):
     def test_user_show(self):
         username = self._create_dummy_user()
         raw_output = self.openstack(
-            'user show ' f'--domain {self.domain_name} ' f'{username}'
+            f'user show --domain {self.domain_name} {username}'
         )
         items = self.parse_show(raw_output)
         self.assert_show_fields(items, self.USER_FIELDS)
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/common.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/common.py	2025-07-07 22:41:56.000000000 +0000
@@ -33,7 +33,7 @@ class NetworkTests(base.TestCase):
 class NetworkTagTests(NetworkTests):
     """Functional tests with tag operation"""
 
-    base_command = None
+    base_command: str
 
     def test_tag_operation(self):
         # Get project IDs
@@ -56,7 +56,7 @@ class NetworkTagTests(NetworkTests):
             'set', name1, '--tag red --tag green', ['red', 'green']
         )
 
-        list_expected = (
+        list_expected: tuple[tuple[str, list[str]], ...] = (
             (name1, ['red', 'green']),
             (name2, ['red', 'blue']),
             (name3, []),
@@ -93,7 +93,11 @@ class NetworkTagTests(NetworkTests):
             parse_output=True,
         )
 
-    def _create_resource_and_tag_check(self, args, expected):
+    def _create_resource_and_tag_check(
+        self,
+        args: str,
+        expected: list[str],
+    ) -> str:
         name = uuid.uuid4().hex
         cmd_output = self._create_resource_for_tag_test(name, args)
         self.addCleanup(self.openstack, f'{self.base_command} delete {name}')
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_address_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_address_group.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_address_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_address_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -75,6 +75,10 @@ class AddressGroupTests(common.NetworkTe
         self.assertNotEqual(admin_project_id, demo_project_id)
         self.assertEqual(admin_project_id, auth_project_id)
 
+        # type narrow
+        assert admin_project_id is not None
+        assert demo_project_id is not None
+
         name1 = uuid.uuid4().hex
         cmd_output = self.openstack(
             'address group create ' + name1,
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py	2025-07-07 22:41:56.000000000 +0000
@@ -69,8 +69,7 @@ class L3ConntrackHelperTests(common.Netw
         ct_ids = " ".join([ct['id'] for ct in created_helpers])
 
         raw_output = self.openstack(
-            f'--debug network l3 conntrack helper delete {router_id} '
-            f'{ct_ids}'
+            f'--debug network l3 conntrack helper delete {router_id} {ct_ids}'
         )
         self.assertOutput('', raw_output)
 
@@ -95,9 +94,14 @@ class L3ConntrackHelperTests(common.Netw
             self.assertIn(ct, expected_helpers)
 
     def test_l3_conntrack_helper_set_and_show(self):
-        helper = {'helper': 'tftp', 'protocol': 'udp', 'port': 69}
+        helper = 'tftp'
+        proto = 'udp'
+        port = 69
         router_id = self._create_router()
-        created_helper = self._create_helpers(router_id, [helper])[0]
+        created_helper = self._create_helpers(
+            router_id,
+            [{'helper': helper, 'protocol': proto, 'port': port}],
+        )[0]
         output = self.openstack(
             'network l3 conntrack helper show {router_id} {ct_id} '
             '-f json'.format(
@@ -106,16 +110,16 @@ class L3ConntrackHelperTests(common.Netw
             ),
             parse_output=True,
         )
-        self.assertEqual(helper['helper'], output['helper'])
-        self.assertEqual(helper['protocol'], output['protocol'])
-        self.assertEqual(helper['port'], output['port'])
+        self.assertEqual(port, output['port'])
+        self.assertEqual(helper, output['helper'])
+        self.assertEqual(proto, output['protocol'])
 
         raw_output = self.openstack(
             'network l3 conntrack helper set {router_id} {ct_id} '
             '--port {port} '.format(
                 router_id=router_id,
                 ct_id=created_helper['id'],
-                port=helper['port'] + 1,
+                port=port + 1,
             )
         )
         self.assertOutput('', raw_output)
@@ -128,6 +132,6 @@ class L3ConntrackHelperTests(common.Netw
             ),
             parse_output=True,
         )
-        self.assertEqual(helper['port'] + 1, output['port'])
-        self.assertEqual(helper['helper'], output['helper'])
-        self.assertEqual(helper['protocol'], output['protocol'])
+        self.assertEqual(port + 1, output['port'])
+        self.assertEqual(helper, output['helper'])
+        self.assertEqual(proto, output['protocol'])
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_local_ip.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_local_ip.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_local_ip.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_local_ip.py	2025-07-07 22:41:56.000000000 +0000
@@ -77,6 +77,10 @@ class LocalIPTests(common.NetworkTests):
         self.assertNotEqual(admin_project_id, demo_project_id)
         self.assertEqual(admin_project_id, auth_project_id)
 
+        # type narrow
+        assert admin_project_id is not None
+        assert demo_project_id is not None
+
         name1 = uuid.uuid4().hex
         cmd_output = self.openstack(
             'local ip create ' + name1,
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_meter_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_meter_rule.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_meter_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_meter_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -22,8 +22,8 @@ from openstackclient.tests.functional.ne
 class TestMeterRule(common.NetworkTests):
     """Functional tests for meter rule"""
 
-    METER_ID = None
-    METER_RULE_ID = None
+    METER_ID: str
+    METER_RULE_ID: str
 
     @classmethod
     def setUpClass(cls):
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py	2025-07-07 22:41:56.000000000 +0000
@@ -31,7 +31,7 @@ class L3NDPProxyTests(common.NetworkTest
         self.created_ndp_proxies = []
 
         json_output = self.openstack(
-            'address scope create --ip-version 6 ' f'{self.ADDR_SCOPE_NAME}',
+            f'address scope create --ip-version 6 {self.ADDR_SCOPE_NAME}',
             parse_output=True,
         )
         self.assertIsNotNone(json_output['id'])
@@ -88,8 +88,7 @@ class L3NDPProxyTests(common.NetworkTest
         self.assertIsNotNone(json_output['id'])
         self.INT_SUB_ID = json_output['id']
         json_output = self.openstack(
-            f'port create --network {self.INT_NET_ID} '
-            f'{self.INT_PORT_NAME}',
+            f'port create --network {self.INT_NET_ID} {self.INT_PORT_NAME}',
             parse_output=True,
         )
         self.assertIsNotNone(json_output['id'])
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_rbac.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_rbac.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_rbac.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_rbac.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,8 +18,8 @@ from openstackclient.tests.functional.ne
 class NetworkRBACTests(common.NetworkTests):
     """Functional tests for network rbac"""
 
-    OBJECT_ID = None
-    ID = None
+    OBJECT_ID: str
+    ID: str
     HEADERS = ['ID']
     FIELDS = ['id']
 
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_trunk.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_trunk.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_network_trunk.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_network_trunk.py	2025-07-07 22:41:56.000000000 +0000
@@ -80,7 +80,7 @@ class NetworkTrunkTests(common.NetworkTe
         self.addCleanup(self.openstack, 'network trunk delete ' + trunk_name)
         self.assertEqual(trunk_name, json_output['name'])
 
-        self.openstack('network trunk set ' '--enable ' + trunk_name)
+        self.openstack('network trunk set --enable ' + trunk_name)
 
         json_output = json.loads(
             self.openstack('network trunk show -f json ' + trunk_name)
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_port.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_port.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_port.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_port.py	2025-07-07 22:41:56.000000000 +0000
@@ -12,6 +12,8 @@
 
 import uuid
 
+from tempest.lib import exceptions as tempest_exc
+
 from openstackclient.tests.functional.network.v2 import common
 
 
@@ -162,8 +164,16 @@ class PortTests(common.NetworkTagTests):
         id_list = [p['ID'] for p in json_output]
         self.assertIn(id1, id_list)
         self.assertIn(id2, id_list)
-        # Check an unknown field exists
-        self.assertIn('device_id', json_output[0])
+        # Check an unknown field does not exist
+        self.assertNotIn('device_id', json_output[0])
+
+        # Test list with only unknown fields
+        exc = self.assertRaises(
+            tempest_exc.CommandFailed,
+            self.openstack,
+            'port list -c device_id',
+        )
+        self.assertIn("No recognized column names in ['device_id']", str(exc))
 
     def test_port_set(self):
         """Test create, set, show, delete"""
@@ -209,7 +219,7 @@ class PortTests(common.NetworkTagTests):
     def test_port_admin_set(self):
         """Test create, set (as admin), show, delete"""
         json_output = self.openstack(
-            'port create ' f'--network {self.NETWORK_NAME} {self.NAME}',
+            f'port create --network {self.NETWORK_NAME} {self.NAME}',
             parse_output=True,
         )
         id_ = json_output.get('id')
@@ -257,7 +267,7 @@ class PortTests(common.NetworkTagTests):
         self.assertEqual([sg_id1], json_output.get('security_group_ids'))
 
         raw_output = self.openstack(
-            'port set ' f'--security-group {sg_name2} {name}'
+            f'port set --security-group {sg_name2} {name}'
         )
         self.assertOutput('', raw_output)
 
@@ -296,17 +306,17 @@ class PortTests(common.NetworkTagTests):
         sport2 = uuid.uuid4().hex
         trunk = uuid.uuid4().hex
         json_output = self.openstack(
-            'port create ' f'--network {self.NETWORK_NAME} {pport}',
+            f'port create --network {self.NETWORK_NAME} {pport}',
             parse_output=True,
         )
         pport_id = json_output.get('id')
         json_output = self.openstack(
-            'port create ' f'--network {self.NETWORK_NAME} {sport1}',
+            f'port create --network {self.NETWORK_NAME} {sport1}',
             parse_output=True,
         )
         sport1_id = json_output.get('id')
         json_output = self.openstack(
-            'port create ' f'--network {self.NETWORK_NAME} {sport2}',
+            f'port create --network {self.NETWORK_NAME} {sport2}',
             parse_output=True,
         )
         sport2_id = json_output.get('id')
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_router.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_router.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_router.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_router.py	2025-07-07 22:41:56.000000000 +0000
@@ -44,6 +44,44 @@ class RouterTests(common.NetworkTagTests
         del_output = self.openstack('router delete ' + name1 + ' ' + name2)
         self.assertOutput('', del_output)
 
+    def test_router_create_with_external_gateway(self):
+        network_name = uuid.uuid4().hex
+        subnet_name = uuid.uuid4().hex
+        qos_policy = uuid.uuid4().hex
+        router_name = uuid.uuid4().hex
+
+        cmd_net = self.openstack(
+            f'network create --external {network_name}', parse_output=True
+        )
+        self.addCleanup(self.openstack, f'network delete {network_name}')
+        network_id = cmd_net['id']
+
+        self.openstack(
+            f'subnet create {subnet_name} '
+            f'--network {network_name} --subnet-range 10.0.0.0/24'
+        )
+
+        cmd_qos = self.openstack(
+            f'network qos policy create {qos_policy}', parse_output=True
+        )
+        self.addCleanup(
+            self.openstack, f'network qos policy delete {qos_policy}'
+        )
+        qos_id = cmd_qos['id']
+
+        self.openstack(
+            f'router create --external-gateway {network_name} '
+            f'--qos-policy {qos_policy} {router_name}'
+        )
+        self.addCleanup(self.openstack, f'router delete {router_name}')
+
+        cmd_output = self.openstack(
+            f'router show {router_name}', parse_output=True
+        )
+        gw_info = cmd_output['external_gateway_info']
+        self.assertEqual(network_id, gw_info['network_id'])
+        self.assertEqual(qos_id, gw_info['qos_policy_id'])
+
     def test_router_list(self):
         """Test create, list filter"""
         # Get project IDs
@@ -68,6 +106,10 @@ class RouterTests(common.NetworkTagTests
         self.assertNotEqual(admin_project_id, demo_project_id)
         self.assertEqual(admin_project_id, auth_project_id)
 
+        # type narrow
+        assert admin_project_id is not None
+        assert demo_project_id is not None
+
         name1 = uuid.uuid4().hex
         name2 = uuid.uuid4().hex
         cmd_output = self.openstack(
diff -pruN 7.4.0-3/openstackclient/tests/functional/network/v2/test_subnet_pool.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_subnet_pool.py
--- 7.4.0-3/openstackclient/tests/functional/network/v2/test_subnet_pool.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/network/v2/test_subnet_pool.py	2025-07-07 22:41:56.000000000 +0000
@@ -63,6 +63,10 @@ class SubnetPoolTests(common.NetworkTagT
         self.assertNotEqual(admin_project_id, demo_project_id)
         self.assertEqual(admin_project_id, auth_project_id)
 
+        # type narrow
+        assert admin_project_id is not None
+        assert demo_project_id is not None
+
         name1 = uuid.uuid4().hex
         name2 = uuid.uuid4().hex
 
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/common.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/common.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,35 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import fixtures
-
-from openstackclient.tests.functional.volume import base as volume_base
-
-
-class BaseVolumeTests(volume_base.BaseVolumeTests):
-    """Base class for Volume functional tests"""
-
-    @classmethod
-    def setUpClass(cls):
-        super().setUpClass()
-        cls.haz_volume_v1 = cls.is_service_enabled('block-storage', '1.0')
-
-    def setUp(self):
-        super().setUp()
-
-        if not self.haz_volume_v1:
-            self.skipTest("No Volume v1 service present")
-
-        ver_fixture = fixtures.EnvironmentVariable(
-            'OS_VOLUME_API_VERSION', '1'
-        )
-        self.useFixture(ver_fixture)
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/test_qos.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_qos.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/test_qos.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_qos.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,100 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import uuid
-
-from openstackclient.tests.functional.volume.v1 import common
-
-
-class QosTests(common.BaseVolumeTests):
-    """Functional tests for volume qos."""
-
-    def test_volume_qos_create_list(self):
-        """Test create, list, delete multiple"""
-        name1 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume qos create ' + name1,
-            parse_output=True,
-        )
-        self.assertEqual(name1, cmd_output['name'])
-
-        name2 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume qos create ' + name2,
-            parse_output=True,
-        )
-        self.assertEqual(name2, cmd_output['name'])
-
-        # Test list
-        cmd_output = self.openstack(
-            'volume qos list',
-            parse_output=True,
-        )
-        names = [x["Name"] for x in cmd_output]
-        self.assertIn(name1, names)
-        self.assertIn(name2, names)
-
-        # Test delete multiple
-        del_output = self.openstack('volume qos delete ' + name1 + ' ' + name2)
-        self.assertOutput('', del_output)
-
-    def test_volume_qos_set_show_unset(self):
-        """Tests create volume qos, set, unset, show, delete"""
-
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume qos create '
-            + '--consumer front-end '
-            + '--property Alpha=a '
-            + name,
-            parse_output=True,
-        )
-        self.addCleanup(self.openstack, 'volume qos delete ' + name)
-        self.assertEqual(name, cmd_output['name'])
-
-        self.assertEqual("front-end", cmd_output['consumer'])
-
-        # Test volume qos set
-        raw_output = self.openstack(
-            'volume qos set '
-            + '--no-property '
-            + '--property Beta=b '
-            + '--property Charlie=c '
-            + name,
-        )
-        self.assertOutput('', raw_output)
-
-        # Test volume qos show
-        cmd_output = self.openstack(
-            'volume qos show ' + name,
-            parse_output=True,
-        )
-        self.assertEqual(name, cmd_output['name'])
-        self.assertEqual(
-            {'Beta': 'b', 'Charlie': 'c'},
-            cmd_output['properties'],
-        )
-
-        # Test volume qos unset
-        raw_output = self.openstack(
-            'volume qos unset ' + '--property Charlie ' + name,
-        )
-        self.assertOutput('', raw_output)
-
-        cmd_output = self.openstack(
-            'volume qos show ' + name,
-            parse_output=True,
-        )
-        self.assertEqual(name, cmd_output['name'])
-        self.assertEqual({'Beta': 'b'}, cmd_output['properties'])
-
-    # TODO(qiangjiahui): Add tests for associate and disassociate volume type
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/test_service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_service.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/test_service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_service.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,76 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from openstackclient.tests.functional.volume.v1 import common
-
-
-class VolumeServiceTests(common.BaseVolumeTests):
-    """Functional tests for volume service."""
-
-    def test_volume_service_list(self):
-        cmd_output = self.openstack('volume service list', parse_output=True)
-
-        # Get the nonredundant services and hosts
-        services = list({x['Binary'] for x in cmd_output})
-
-        # Test volume service list --service
-        cmd_output = self.openstack(
-            'volume service list ' + '--service ' + services[0],
-            parse_output=True,
-        )
-        for x in cmd_output:
-            self.assertEqual(services[0], x['Binary'])
-
-        # TODO(zhiyong.dai): test volume service list --host after solving
-        # https://bugs.launchpad.net/python-openstackclient/+bug/1664451
-
-    def test_volume_service_set(self):
-        # Get a service and host
-        cmd_output = self.openstack(
-            'volume service list',
-            parse_output=True,
-        )
-        service_1 = cmd_output[0]['Binary']
-        host_1 = cmd_output[0]['Host']
-
-        # Test volume service set --enable
-        raw_output = self.openstack(
-            'volume service set --enable ' + host_1 + ' ' + service_1
-        )
-        self.assertOutput('', raw_output)
-
-        cmd_output = self.openstack(
-            'volume service list --long',
-            parse_output=True,
-        )
-        self.assertEqual('enabled', cmd_output[0]['Status'])
-        self.assertIsNone(cmd_output[0]['Disabled Reason'])
-
-        # Test volume service set --disable and --disable-reason
-        disable_reason = 'disable_reason'
-        raw_output = self.openstack(
-            'volume service set --disable '
-            + '--disable-reason '
-            + disable_reason
-            + ' '
-            + host_1
-            + ' '
-            + service_1
-        )
-        self.assertOutput('', raw_output)
-
-        cmd_output = self.openstack(
-            'volume service list --long',
-            parse_output=True,
-        )
-        self.assertEqual('disabled', cmd_output[0]['Status'])
-        self.assertEqual(disable_reason, cmd_output[0]['Disabled Reason'])
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/test_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_snapshot.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/test_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_snapshot.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,232 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import uuid
-
-from openstackclient.tests.functional.volume.v1 import common
-
-
-class VolumeSnapshotTests(common.BaseVolumeTests):
-    """Functional tests for volume snapshot."""
-
-    VOLLY = uuid.uuid4().hex
-
-    @classmethod
-    def setUpClass(cls):
-        super().setUpClass()
-        # create a volume for all tests to create snapshot
-        cmd_output = cls.openstack(
-            'volume create ' + '--size 1 ' + cls.VOLLY,
-            parse_output=True,
-        )
-        cls.wait_for_status('volume', cls.VOLLY, 'available')
-        cls.VOLUME_ID = cmd_output['id']
-
-    @classmethod
-    def tearDownClass(cls):
-        try:
-            cls.wait_for_status('volume', cls.VOLLY, 'available')
-            raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
-            cls.assertOutput('', raw_output)
-        finally:
-            super().tearDownClass()
-
-    def test_volume_snapshot_delete(self):
-        """Test create, delete multiple"""
-        name1 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
-            parse_output=True,
-        )
-        self.assertEqual(
-            name1,
-            cmd_output["display_name"],
-        )
-
-        name2 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
-            parse_output=True,
-        )
-        self.assertEqual(
-            name2,
-            cmd_output["display_name"],
-        )
-
-        self.wait_for_status('volume snapshot', name1, 'available')
-        self.wait_for_status('volume snapshot', name2, 'available')
-
-        del_output = self.openstack(
-            'volume snapshot delete ' + name1 + ' ' + name2
-        )
-        self.assertOutput('', del_output)
-        self.wait_for_delete('volume snapshot', name1)
-        self.wait_for_delete('volume snapshot', name2)
-
-    def test_volume_snapshot_list(self):
-        """Test create, list filter"""
-        name1 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
-            parse_output=True,
-        )
-        self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
-        self.addCleanup(self.openstack, 'volume snapshot delete ' + name1)
-        self.assertEqual(
-            name1,
-            cmd_output["display_name"],
-        )
-        self.assertEqual(
-            self.VOLUME_ID,
-            cmd_output["volume_id"],
-        )
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-        self.wait_for_status('volume snapshot', name1, 'available')
-
-        name2 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
-            parse_output=True,
-        )
-        self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
-        self.addCleanup(self.openstack, 'volume snapshot delete ' + name2)
-        self.assertEqual(
-            name2,
-            cmd_output["display_name"],
-        )
-        self.assertEqual(
-            self.VOLUME_ID,
-            cmd_output["volume_id"],
-        )
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-        self.wait_for_status('volume snapshot', name2, 'available')
-
-        # Test list --long, --status
-        cmd_output = self.openstack(
-            'volume snapshot list ' + '--long ' + '--status error',
-            parse_output=True,
-        )
-        names = [x["Name"] for x in cmd_output]
-        self.assertNotIn(name1, names)
-        self.assertNotIn(name2, names)
-
-        # Test list --volume
-        cmd_output = self.openstack(
-            'volume snapshot list ' + '--volume ' + self.VOLLY,
-            parse_output=True,
-        )
-        names = [x["Name"] for x in cmd_output]
-        self.assertIn(name1, names)
-        self.assertIn(name2, names)
-
-        # Test list --name
-        cmd_output = self.openstack(
-            'volume snapshot list ' + '--name ' + name1,
-            parse_output=True,
-        )
-        names = [x["Name"] for x in cmd_output]
-        self.assertIn(name1, names)
-        self.assertNotIn(name2, names)
-
-    def test_snapshot_set(self):
-        """Test create, set, unset, show, delete volume snapshot"""
-        name = uuid.uuid4().hex
-        new_name = name + "_"
-        cmd_output = self.openstack(
-            'volume snapshot create '
-            + '--volume '
-            + self.VOLLY
-            + ' --description aaaa '
-            + name,
-            parse_output=True,
-        )
-        self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
-        self.addCleanup(self.openstack, 'volume snapshot delete ' + new_name)
-        self.assertEqual(
-            name,
-            cmd_output["display_name"],
-        )
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-        self.assertEqual(
-            'aaaa',
-            cmd_output["display_description"],
-        )
-        self.wait_for_status('volume snapshot', name, 'available')
-
-        # Test volume snapshot set
-        raw_output = self.openstack(
-            'volume snapshot set '
-            + '--name '
-            + new_name
-            + ' --description bbbb '
-            + '--property Alpha=a '
-            + '--property Beta=b '
-            + name,
-        )
-        self.assertOutput('', raw_output)
-
-        # Show snapshot set result
-        cmd_output = self.openstack(
-            'volume snapshot show ' + new_name,
-            parse_output=True,
-        )
-        self.assertEqual(
-            new_name,
-            cmd_output["display_name"],
-        )
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-        self.assertEqual(
-            'bbbb',
-            cmd_output["display_description"],
-        )
-        self.assertEqual(
-            {'Alpha': 'a', 'Beta': 'b'},
-            cmd_output["properties"],
-        )
-
-        # Test volume unset
-        raw_output = self.openstack(
-            'volume snapshot unset ' + '--property Alpha ' + new_name,
-        )
-        self.assertOutput('', raw_output)
-
-        cmd_output = self.openstack(
-            'volume snapshot show ' + new_name,
-            parse_output=True,
-        )
-        self.assertEqual(
-            {'Beta': 'b'},
-            cmd_output["properties"],
-        )
-
-        # Test volume snapshot set --no-property
-        raw_output = self.openstack(
-            'volume snapshot set ' + '--no-property ' + new_name,
-        )
-        self.assertOutput('', raw_output)
-        cmd_output = self.openstack(
-            'volume snapshot show ' + new_name,
-            parse_output=True,
-        )
-        self.assertEqual({}, cmd_output["properties"])
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/test_transfer_request.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_transfer_request.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/test_transfer_request.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_transfer_request.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,111 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import uuid
-
-from openstackclient.tests.functional.volume.v1 import common
-
-
-class TransferRequestTests(common.BaseVolumeTests):
-    """Functional tests for transfer request."""
-
-    NAME = uuid.uuid4().hex
-    VOLUME_NAME = uuid.uuid4().hex
-
-    @classmethod
-    def setUpClass(cls):
-        super().setUpClass()
-        cmd_output = cls.openstack(
-            'volume create --size 1 ' + cls.VOLUME_NAME,
-            parse_output=True,
-        )
-        cls.assertOutput(cls.VOLUME_NAME, cmd_output['name'])
-
-        cls.wait_for_status("volume", cls.VOLUME_NAME, "available")
-
-    @classmethod
-    def tearDownClass(cls):
-        try:
-            raw_output_volume = cls.openstack(
-                'volume delete ' + cls.VOLUME_NAME
-            )
-            cls.assertOutput('', raw_output_volume)
-        finally:
-            super().tearDownClass()
-
-    def test_volume_transfer_request_accept(self):
-        volume_name = uuid.uuid4().hex
-        name = uuid.uuid4().hex
-
-        # create a volume
-        cmd_output = self.openstack(
-            'volume create --size 1 ' + volume_name,
-            parse_output=True,
-        )
-        self.assertEqual(volume_name, cmd_output['name'])
-
-        # create volume transfer request for the volume
-        # and get the auth_key of the new transfer request
-        cmd_output = self.openstack(
-            'volume transfer request create '
-            + volume_name
-            + ' --name '
-            + name,
-            parse_output=True,
-        )
-        auth_key = cmd_output['auth_key']
-        self.assertTrue(auth_key)
-
-        # accept the volume transfer request
-        output = self.openstack(
-            'volume transfer request accept '
-            + name
-            + ' '
-            + '--auth-key '
-            + auth_key,
-            parse_output=True,
-        )
-        self.assertEqual(name, output.get('name'))
-
-        # the volume transfer will be removed by default after accepted
-        # so just need to delete the volume here
-        raw_output = self.openstack('volume delete ' + volume_name)
-        self.assertEqual('', raw_output)
-
-    def test_volume_transfer_request_list_show(self):
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume transfer request create '
-            + ' --name '
-            + name
-            + ' '
-            + self.VOLUME_NAME,
-            parse_output=True,
-        )
-        self.addCleanup(
-            self.openstack, 'volume transfer request delete ' + name
-        )
-        self.assertOutput(name, cmd_output['name'])
-        auth_key = cmd_output['auth_key']
-        self.assertTrue(auth_key)
-
-        cmd_output = self.openstack(
-            'volume transfer request list',
-            parse_output=True,
-        )
-        self.assertIn(name, [req['Name'] for req in cmd_output])
-
-        cmd_output = self.openstack(
-            'volume transfer request show ' + name,
-            parse_output=True,
-        )
-        self.assertEqual(name, cmd_output['name'])
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/test_volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_volume.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/test_volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_volume.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,228 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import uuid
-
-from openstackclient.tests.functional.volume.v1 import common
-
-
-class VolumeTests(common.BaseVolumeTests):
-    """Functional tests for volume."""
-
-    def test_volume_create_and_delete(self):
-        """Test create, delete multiple"""
-        name1 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume create ' + '--size 1 ' + name1,
-            parse_output=True,
-        )
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-
-        name2 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume create ' + '--size 2 ' + name2,
-            parse_output=True,
-        )
-        self.assertEqual(
-            2,
-            cmd_output["size"],
-        )
-
-        self.wait_for_status("volume", name1, "available")
-        self.wait_for_status("volume", name2, "available")
-        del_output = self.openstack('volume delete ' + name1 + ' ' + name2)
-        self.assertOutput('', del_output)
-
-    def test_volume_list(self):
-        """Test create, list filter"""
-        name1 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume create ' + '--size 1 ' + name1,
-            parse_output=True,
-        )
-        self.addCleanup(self.openstack, 'volume delete ' + name1)
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-        self.wait_for_status("volume", name1, "available")
-
-        name2 = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume create ' + '--size 2 ' + name2,
-            parse_output=True,
-        )
-        self.addCleanup(self.openstack, 'volume delete ' + name2)
-        self.assertEqual(
-            2,
-            cmd_output["size"],
-        )
-        self.wait_for_status("volume", name2, "available")
-
-        # Test list
-        cmd_output = self.openstack(
-            'volume list ',
-            parse_output=True,
-        )
-        names = [x["Name"] for x in cmd_output]
-        self.assertIn(name1, names)
-        self.assertIn(name2, names)
-
-        # Test list --long
-        cmd_output = self.openstack(
-            'volume list --long',
-            parse_output=True,
-        )
-        bootable = [x["Bootable"] for x in cmd_output]
-        self.assertIn('false', bootable)
-
-        # Test list --name
-        cmd_output = self.openstack(
-            'volume list ' + '--name ' + name1,
-            parse_output=True,
-        )
-        names = [x["Name"] for x in cmd_output]
-        self.assertIn(name1, names)
-        self.assertNotIn(name2, names)
-
-    def test_volume_set_and_unset(self):
-        """Tests create volume, set, unset, show, delete"""
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume create '
-            + '--size 1 '
-            + '--description aaaa '
-            + '--property Alpha=a '
-            + name,
-            parse_output=True,
-        )
-        self.assertEqual(
-            name,
-            cmd_output["name"],
-        )
-        self.assertEqual(
-            1,
-            cmd_output["size"],
-        )
-        self.assertEqual(
-            'aaaa',
-            cmd_output["display_description"],
-        )
-        self.assertEqual(
-            {'Alpha': 'a'},
-            cmd_output["properties"],
-        )
-        self.assertEqual(
-            'false',
-            cmd_output["bootable"],
-        )
-        self.wait_for_status("volume", name, "available")
-
-        # Test volume set
-        new_name = uuid.uuid4().hex
-        self.addCleanup(self.openstack, 'volume delete ' + new_name)
-        raw_output = self.openstack(
-            'volume set '
-            + '--name '
-            + new_name
-            + ' --size 2 '
-            + '--description bbbb '
-            + '--no-property '
-            + '--property Beta=b '
-            + '--property Gamma=c '
-            + '--bootable '
-            + name,
-        )
-        self.assertOutput('', raw_output)
-
-        cmd_output = self.openstack(
-            'volume show ' + new_name,
-            parse_output=True,
-        )
-        self.assertEqual(
-            new_name,
-            cmd_output["name"],
-        )
-        self.assertEqual(
-            2,
-            cmd_output["size"],
-        )
-        self.assertEqual(
-            'bbbb',
-            cmd_output["display_description"],
-        )
-        self.assertEqual(
-            {'Beta': 'b', 'Gamma': 'c'},
-            cmd_output["properties"],
-        )
-        self.assertEqual(
-            'true',
-            cmd_output["bootable"],
-        )
-
-        # Test volume unset
-        raw_output = self.openstack(
-            'volume unset ' + '--property Beta ' + new_name,
-        )
-        self.assertOutput('', raw_output)
-
-        cmd_output = self.openstack(
-            'volume show ' + new_name,
-            parse_output=True,
-        )
-        self.assertEqual(
-            {'Gamma': 'c'},
-            cmd_output["properties"],
-        )
-
-    def test_volume_create_and_list_and_show_backward_compatibility(self):
-        """Test backward compatibility of create, list, show"""
-        name1 = uuid.uuid4().hex
-        output = self.openstack(
-            'volume create ' + '-c display_name -c id ' + '--size 1 ' + name1,
-            parse_output=True,
-        )
-        self.assertIn('display_name', output)
-        self.assertEqual(name1, output['display_name'])
-        self.assertIn('id', output)
-        volume_id = output['id']
-        self.assertIsNotNone(volume_id)
-        self.assertNotIn('name', output)
-        self.addCleanup(self.openstack, 'volume delete ' + volume_id)
-
-        self.wait_for_status("volume", name1, "available")
-
-        output = self.openstack(
-            'volume list ' + '-c "Display Name"',
-            parse_output=True,
-        )
-        for each_volume in output:
-            self.assertIn('Display Name', each_volume)
-
-        output = self.openstack(
-            'volume list ' + '-c "Name"',
-            parse_output=True,
-        )
-        for each_volume in output:
-            self.assertIn('Name', each_volume)
-
-        output = self.openstack(
-            'volume show ' + '-c display_name -c id ' + name1,
-            parse_output=True,
-        )
-        self.assertIn('display_name', output)
-        self.assertEqual(name1, output['display_name'])
-        self.assertIn('id', output)
-        self.assertNotIn('name', output)
diff -pruN 7.4.0-3/openstackclient/tests/functional/volume/v1/test_volume_type.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_volume_type.py
--- 7.4.0-3/openstackclient/tests/functional/volume/v1/test_volume_type.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/functional/volume/v1/test_volume_type.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,213 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import time
-import uuid
-
-from openstackclient.tests.functional.volume.v1 import common
-
-
-class VolumeTypeTests(common.BaseVolumeTests):
-    """Functional tests for volume type."""
-
-    def test_volume_type_create_list(self):
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume type create --private ' + name,
-            parse_output=True,
-        )
-        self.addCleanup(
-            self.openstack,
-            'volume type delete ' + name,
-        )
-        self.assertEqual(name, cmd_output['name'])
-
-        cmd_output = self.openstack(
-            f'volume type show {name}',
-            parse_output=True,
-        )
-        self.assertEqual(self.NAME, cmd_output['name'])
-
-        cmd_output = self.openstack('volume type list', parse_output=True)
-        self.assertIn(self.NAME, [t['Name'] for t in cmd_output])
-
-        cmd_output = self.openstack(
-            'volume type list --default',
-            parse_output=True,
-        )
-        self.assertEqual(1, len(cmd_output))
-        self.assertEqual('lvmdriver-1', cmd_output[0]['Name'])
-
-    def test_volume_type_set_unset_properties(self):
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume type create --private ' + name,
-            parse_output=True,
-        )
-        self.addCleanup(self.openstack, 'volume type delete ' + name)
-        self.assertEqual(name, cmd_output['name'])
-
-        raw_output = self.openstack(
-            f'volume type set --property a=b --property c=d {name}'
-        )
-        self.assertEqual("", raw_output)
-        cmd_output = self.openstack(
-            f'volume type show {name}',
-            parse_output=True,
-        )
-        self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
-
-        raw_output = self.openstack(f'volume type unset --property a {name}')
-        self.assertEqual("", raw_output)
-        cmd_output = self.openstack(
-            f'volume type show {name}',
-            parse_output=True,
-        )
-        self.assertEqual({'c': 'd'}, cmd_output['properties'])
-
-    def test_volume_type_set_unset_multiple_properties(self):
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume type create --private ' + name,
-            parse_output=True,
-        )
-        self.addCleanup(self.openstack, 'volume type delete ' + name)
-        self.assertEqual(name, cmd_output['name'])
-
-        raw_output = self.openstack(
-            f'volume type set --property a=b --property c=d {name}'
-        )
-        self.assertEqual("", raw_output)
-        cmd_output = self.openstack(
-            f'volume type show {name}',
-            parse_output=True,
-        )
-        self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
-
-        raw_output = self.openstack(
-            f'volume type unset --property a --property c {name}'
-        )
-        self.assertEqual("", raw_output)
-        cmd_output = self.openstack(
-            f'volume type show {name}',
-            parse_output=True,
-        )
-        self.assertEqual({}, cmd_output['properties'])
-
-    def test_multi_delete(self):
-        vol_type1 = uuid.uuid4().hex
-        vol_type2 = uuid.uuid4().hex
-        self.openstack(f'volume type create {vol_type1}')
-        time.sleep(5)
-        self.openstack(f'volume type create {vol_type2}')
-        time.sleep(5)
-        cmd = f'volume type delete {vol_type1} {vol_type2}'
-        raw_output = self.openstack(cmd)
-        self.assertOutput('', raw_output)
-
-    # NOTE: Add some basic functional tests with the old format to
-    #       make sure the command works properly, need to change
-    #       these to new test format when beef up all tests for
-    #       volume type commands.
-    def test_encryption_type(self):
-        encryption_type = uuid.uuid4().hex
-        # test create new encryption type
-        cmd_output = self.openstack(
-            'volume type create '
-            '--encryption-provider LuksEncryptor '
-            '--encryption-cipher aes-xts-plain64 '
-            '--encryption-key-size 128 '
-            '--encryption-control-location front-end ' + encryption_type
-        )
-        expected = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': 128,
-            'control_location': 'front-end',
-        }
-        for attr, value in expected.items():
-            self.assertEqual(value, cmd_output['encryption'][attr])
-        # test show encryption type
-        cmd_output = self.openstack(
-            'volume type show --encryption-type ' + encryption_type,
-            parse_output=True,
-        )
-        expected = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': 128,
-            'control_location': 'front-end',
-        }
-        for attr, value in expected.items():
-            self.assertEqual(value, cmd_output['encryption'][attr])
-        # test list encryption type
-        cmd_output = self.openstack(
-            'volume type list --encryption-type',
-            parse_output=True,
-        )
-        encryption_output = [
-            t['Encryption'] for t in cmd_output if t['Name'] == encryption_type
-        ][0]
-        expected = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': 128,
-            'control_location': 'front-end',
-        }
-        for attr, value in expected.items():
-            self.assertEqual(value, encryption_output[attr])
-        # test set new encryption type
-        raw_output = self.openstack(
-            'volume type set '
-            '--encryption-provider LuksEncryptor '
-            '--encryption-cipher aes-xts-plain64 '
-            '--encryption-key-size 128 '
-            '--encryption-control-location front-end ' + self.NAME
-        )
-        self.assertEqual('', raw_output)
-
-        name = uuid.uuid4().hex
-        cmd_output = self.openstack(
-            'volume type create --private ' + name,
-            parse_output=True,
-        )
-        self.addCleanup(
-            self.openstack,
-            'volume type delete ' + name,
-        )
-        self.assertEqual(name, cmd_output['name'])
-
-        cmd_output = self.openstack(
-            'volume type show --encryption-type ' + name,
-            parse_output=True,
-        )
-        expected = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': 128,
-            'control_location': 'front-end',
-        }
-        for attr, value in expected.items():
-            self.assertEqual(value, cmd_output['encryption'][attr])
-        # test unset encryption type
-        raw_output = self.openstack(
-            'volume type unset --encryption-type ' + name
-        )
-        self.assertEqual('', raw_output)
-        cmd_output = self.openstack(
-            'volume type show --encryption-type ' + name,
-            parse_output=True,
-        )
-        self.assertEqual({}, cmd_output['encryption'])
-        # test delete encryption type
-        raw_output = self.openstack('volume type delete ' + encryption_type)
-        self.assertEqual('', raw_output)
diff -pruN 7.4.0-3/openstackclient/tests/unit/api/test_compute_v2.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/api/test_compute_v2.py
--- 7.4.0-3/openstackclient/tests/unit/api/test_compute_v2.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/api/test_compute_v2.py	2025-07-07 22:41:56.000000000 +0000
@@ -29,7 +29,7 @@ class TestSecurityGroup(utils.TestCase):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client = mock.Mock(_proxy.Proxy)
+        self.compute_client = mock.Mock(_proxy.Proxy)
 
     def test_create_security_group(self):
         sg_name = 'name-' + uuid.uuid4().hex
@@ -43,15 +43,13 @@ class TestSecurityGroup(utils.TestCase):
                 'rules': [],
             }
         }
-        self.compute_sdk_client.post.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.post.return_value = fakes.FakeResponse(data=data)
 
         result = compute.create_security_group(
-            self.compute_sdk_client, sg_name, sg_description
+            self.compute_client, sg_name, sg_description
         )
 
-        self.compute_sdk_client.post.assert_called_once_with(
+        self.compute_client.post.assert_called_once_with(
             '/os-security-groups',
             data={'name': sg_name, 'description': sg_description},
             microversion='2.1',
@@ -70,13 +68,11 @@ class TestSecurityGroup(utils.TestCase):
                 }
             ],
         }
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.get.return_value = fakes.FakeResponse(data=data)
 
-        result = compute.list_security_groups(self.compute_sdk_client)
+        result = compute.list_security_groups(self.compute_client)
 
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             '/os-security-groups', microversion='2.1'
         )
         self.assertEqual(data['security_groups'], result)
@@ -93,13 +89,13 @@ class TestSecurityGroup(utils.TestCase):
                 'rules': [],
             }
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(data=data),
         ]
 
-        result = compute.find_security_group(self.compute_sdk_client, sg_id)
+        result = compute.find_security_group(self.compute_client, sg_id)
 
-        self.compute_sdk_client.get.assert_has_calls(
+        self.compute_client.get.assert_has_calls(
             [
                 mock.call(f'/os-security-groups/{sg_id}', microversion='2.1'),
             ]
@@ -120,14 +116,14 @@ class TestSecurityGroup(utils.TestCase):
                 }
             ],
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
             fakes.FakeResponse(data=data),
         ]
 
-        result = compute.find_security_group(self.compute_sdk_client, sg_name)
+        result = compute.find_security_group(self.compute_client, sg_name)
 
-        self.compute_sdk_client.get.assert_has_calls(
+        self.compute_client.get.assert_has_calls(
             [
                 mock.call(
                     f'/os-security-groups/{sg_name}', microversion='2.1'
@@ -139,14 +135,14 @@ class TestSecurityGroup(utils.TestCase):
 
     def test_find_security_group_not_found(self):
         data = {'security_groups': []}
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
             fakes.FakeResponse(data=data),
         ]
         self.assertRaises(
             osc_lib_exceptions.NotFound,
             compute.find_security_group,
-            self.compute_sdk_client,
+            self.compute_client,
             'invalid-sg',
         )
 
@@ -170,7 +166,7 @@ class TestSecurityGroup(utils.TestCase):
                 },
             ],
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
             fakes.FakeResponse(data=data),
         ]
@@ -178,7 +174,7 @@ class TestSecurityGroup(utils.TestCase):
         self.assertRaises(
             osc_lib_exceptions.NotFound,
             compute.find_security_group,
-            self.compute_sdk_client,
+            self.compute_client,
             sg_name,
         )
 
@@ -195,15 +191,13 @@ class TestSecurityGroup(utils.TestCase):
                 'rules': [],
             }
         }
-        self.compute_sdk_client.put.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.put.return_value = fakes.FakeResponse(data=data)
 
         result = compute.update_security_group(
-            self.compute_sdk_client, sg_id, sg_name, sg_description
+            self.compute_client, sg_id, sg_name, sg_description
         )
 
-        self.compute_sdk_client.put.assert_called_once_with(
+        self.compute_client.put.assert_called_once_with(
             f'/os-security-groups/{sg_id}',
             data={'name': sg_name, 'description': sg_description},
             microversion='2.1',
@@ -212,13 +206,13 @@ class TestSecurityGroup(utils.TestCase):
 
     def test_delete_security_group(self):
         sg_id = uuid.uuid4().hex
-        self.compute_sdk_client.delete.return_value = fakes.FakeResponse(
+        self.compute_client.delete.return_value = fakes.FakeResponse(
             status_code=http.HTTPStatus.NO_CONTENT
         )
 
-        result = compute.delete_security_group(self.compute_sdk_client, sg_id)
+        result = compute.delete_security_group(self.compute_client, sg_id)
 
-        self.compute_sdk_client.delete.assert_called_once_with(
+        self.compute_client.delete.assert_called_once_with(
             f'/os-security-groups/{sg_id}',
             microversion='2.1',
         )
@@ -229,7 +223,7 @@ class TestSecurityGroupRule(utils.TestCa
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client = mock.Mock(_proxy.Proxy)
+        self.compute_client = mock.Mock(_proxy.Proxy)
 
     def test_create_security_group_rule(self):
         sg_id = uuid.uuid4().hex
@@ -242,12 +236,10 @@ class TestSecurityGroupRule(utils.TestCa
                 'cidr': '10.0.0.0/24',
             }
         }
-        self.compute_sdk_client.post.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.post.return_value = fakes.FakeResponse(data=data)
 
         result = compute.create_security_group_rule(
-            self.compute_sdk_client,
+            self.compute_client,
             security_group_id=sg_id,
             ip_protocol='tcp',
             from_port=22,
@@ -256,7 +248,7 @@ class TestSecurityGroupRule(utils.TestCa
             remote_group=None,
         )
 
-        self.compute_sdk_client.post.assert_called_once_with(
+        self.compute_client.post.assert_called_once_with(
             '/os-security-group-rules',
             data={
                 'parent_group_id': sg_id,
@@ -272,15 +264,13 @@ class TestSecurityGroupRule(utils.TestCa
 
     def test_delete_security_group_rule(self):
         sg_id = uuid.uuid4().hex
-        self.compute_sdk_client.delete.return_value = fakes.FakeResponse(
+        self.compute_client.delete.return_value = fakes.FakeResponse(
             status_code=http.HTTPStatus.NO_CONTENT
         )
 
-        result = compute.delete_security_group_rule(
-            self.compute_sdk_client, sg_id
-        )
+        result = compute.delete_security_group_rule(self.compute_client, sg_id)
 
-        self.compute_sdk_client.delete.assert_called_once_with(
+        self.compute_client.delete.assert_called_once_with(
             f'/os-security-group-rules/{sg_id}',
             microversion='2.1',
         )
@@ -291,7 +281,7 @@ class TestNetwork(utils.TestCase):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client = mock.Mock(_proxy.Proxy)
+        self.compute_client = mock.Mock(_proxy.Proxy)
 
     def test_create_network(self):
         net_name = 'name-' + uuid.uuid4().hex
@@ -305,18 +295,16 @@ class TestNetwork(utils.TestCase):
                 # other fields omitted for brevity
             }
         }
-        self.compute_sdk_client.post.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.post.return_value = fakes.FakeResponse(data=data)
 
         result = compute.create_network(
-            self.compute_sdk_client,
+            self.compute_client,
             name=net_name,
             subnet=net_subnet,
             share_subnet=True,
         )
 
-        self.compute_sdk_client.post.assert_called_once_with(
+        self.compute_client.post.assert_called_once_with(
             '/os-networks',
             data={
                 'label': net_name,
@@ -337,13 +325,11 @@ class TestNetwork(utils.TestCase):
                 }
             ],
         }
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.get.return_value = fakes.FakeResponse(data=data)
 
-        result = compute.list_networks(self.compute_sdk_client)
+        result = compute.list_networks(self.compute_client)
 
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             '/os-networks', microversion='2.1'
         )
         self.assertEqual(data['networks'], result)
@@ -358,13 +344,13 @@ class TestNetwork(utils.TestCase):
                 # other fields omitted for brevity
             }
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(data=data),
         ]
 
-        result = compute.find_network(self.compute_sdk_client, net_id)
+        result = compute.find_network(self.compute_client, net_id)
 
-        self.compute_sdk_client.get.assert_has_calls(
+        self.compute_client.get.assert_has_calls(
             [
                 mock.call(f'/os-networks/{net_id}', microversion='2.1'),
             ]
@@ -383,14 +369,14 @@ class TestNetwork(utils.TestCase):
                 }
             ],
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
             fakes.FakeResponse(data=data),
         ]
 
-        result = compute.find_network(self.compute_sdk_client, net_name)
+        result = compute.find_network(self.compute_client, net_name)
 
-        self.compute_sdk_client.get.assert_has_calls(
+        self.compute_client.get.assert_has_calls(
             [
                 mock.call(f'/os-networks/{net_name}', microversion='2.1'),
                 mock.call('/os-networks', microversion='2.1'),
@@ -400,14 +386,14 @@ class TestNetwork(utils.TestCase):
 
     def test_find_network_not_found(self):
         data = {'networks': []}
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
             fakes.FakeResponse(data=data),
         ]
         self.assertRaises(
             osc_lib_exceptions.NotFound,
             compute.find_network,
-            self.compute_sdk_client,
+            self.compute_client,
             'invalid-net',
         )
 
@@ -427,7 +413,7 @@ class TestNetwork(utils.TestCase):
                 },
             ],
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
             fakes.FakeResponse(data=data),
         ]
@@ -435,19 +421,19 @@ class TestNetwork(utils.TestCase):
         self.assertRaises(
             osc_lib_exceptions.NotFound,
             compute.find_network,
-            self.compute_sdk_client,
+            self.compute_client,
             net_name,
         )
 
     def test_delete_network(self):
         net_id = uuid.uuid4().hex
-        self.compute_sdk_client.delete.return_value = fakes.FakeResponse(
+        self.compute_client.delete.return_value = fakes.FakeResponse(
             status_code=http.HTTPStatus.NO_CONTENT
         )
 
-        result = compute.delete_network(self.compute_sdk_client, net_id)
+        result = compute.delete_network(self.compute_client, net_id)
 
-        self.compute_sdk_client.delete.assert_called_once_with(
+        self.compute_client.delete.assert_called_once_with(
             f'/os-networks/{net_id}', microversion='2.1'
         )
         self.assertIsNone(result)
@@ -457,7 +443,7 @@ class TestFloatingIP(utils.TestCase):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client = mock.Mock(_proxy.Proxy)
+        self.compute_client = mock.Mock(_proxy.Proxy)
 
     def test_create_floating_ip(self):
         network = 'network-' + uuid.uuid4().hex
@@ -470,15 +456,13 @@ class TestFloatingIP(utils.TestCase):
                 'pool': network,
             }
         }
-        self.compute_sdk_client.post.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.post.return_value = fakes.FakeResponse(data=data)
 
         result = compute.create_floating_ip(
-            self.compute_sdk_client, network=network
+            self.compute_client, network=network
         )
 
-        self.compute_sdk_client.post.assert_called_once_with(
+        self.compute_client.post.assert_called_once_with(
             '/os-floating-ips', data={'pool': network}, microversion='2.1'
         )
         self.assertEqual(data['floating_ip'], result)
@@ -495,13 +479,11 @@ class TestFloatingIP(utils.TestCase):
                 }
             ],
         }
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.get.return_value = fakes.FakeResponse(data=data)
 
-        result = compute.list_floating_ips(self.compute_sdk_client)
+        result = compute.list_floating_ips(self.compute_client)
 
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             '/os-floating-ips', microversion='2.1'
         )
         self.assertEqual(data['floating_ips'], result)
@@ -517,26 +499,26 @@ class TestFloatingIP(utils.TestCase):
                 'pool': f'network-{uuid.uuid4().hex}',
             }
         }
-        self.compute_sdk_client.get.side_effect = [
+        self.compute_client.get.side_effect = [
             fakes.FakeResponse(data=data),
         ]
 
-        result = compute.get_floating_ip(self.compute_sdk_client, fip_id)
+        result = compute.get_floating_ip(self.compute_client, fip_id)
 
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             f'/os-floating-ips/{fip_id}', microversion='2.1'
         )
         self.assertEqual(data['floating_ip'], result)
 
     def test_delete_floating_ip(self):
         fip_id = uuid.uuid4().hex
-        self.compute_sdk_client.delete.return_value = fakes.FakeResponse(
+        self.compute_client.delete.return_value = fakes.FakeResponse(
             status_code=http.HTTPStatus.NO_CONTENT
         )
 
-        result = compute.delete_floating_ip(self.compute_sdk_client, fip_id)
+        result = compute.delete_floating_ip(self.compute_client, fip_id)
 
-        self.compute_sdk_client.delete.assert_called_once_with(
+        self.compute_client.delete.assert_called_once_with(
             f'/os-floating-ips/{fip_id}', microversion='2.1'
         )
         self.assertIsNone(result)
@@ -546,7 +528,7 @@ class TestFloatingIPPool(utils.TestCase)
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client = mock.Mock(_proxy.Proxy)
+        self.compute_client = mock.Mock(_proxy.Proxy)
 
     def test_list_floating_ip_pools(self):
         data = {
@@ -556,13 +538,11 @@ class TestFloatingIPPool(utils.TestCase)
                 }
             ],
         }
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
-            data=data
-        )
+        self.compute_client.get.return_value = fakes.FakeResponse(data=data)
 
-        result = compute.list_floating_ip_pools(self.compute_sdk_client)
+        result = compute.list_floating_ip_pools(self.compute_client)
 
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             '/os-floating-ip-pools', microversion='2.1'
         )
         self.assertEqual(data['floating_ip_pools'], result)
diff -pruN 7.4.0-3/openstackclient/tests/unit/common/test_availability_zone.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_availability_zone.py
--- 7.4.0-3/openstackclient/tests/unit/common/test_availability_zone.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_availability_zone.py	2025-07-07 22:41:56.000000000 +0000
@@ -99,9 +99,7 @@ class TestAvailabilityZoneList(
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.availability_zones.return_value = (
-            self.compute_azs
-        )
+        self.compute_client.availability_zones.return_value = self.compute_azs
         self.volume_sdk_client.availability_zones.return_value = (
             self.volume_azs
         )
@@ -120,9 +118,7 @@ class TestAvailabilityZoneList(
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.availability_zones.assert_called_with(
-            details=True
-        )
+        self.compute_client.availability_zones.assert_called_with(details=True)
         self.volume_sdk_client.availability_zones.assert_called_with()
         self.network_client.availability_zones.assert_called_with()
 
@@ -150,9 +146,7 @@ class TestAvailabilityZoneList(
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.availability_zones.assert_called_with(
-            details=True
-        )
+        self.compute_client.availability_zones.assert_called_with(details=True)
         self.volume_sdk_client.availability_zones.assert_called_with()
         self.network_client.availability_zones.assert_called_with()
 
@@ -186,9 +180,7 @@ class TestAvailabilityZoneList(
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.availability_zones.assert_called_with(
-            details=True
-        )
+        self.compute_client.availability_zones.assert_called_with(details=True)
         self.volume_sdk_client.availability_zones.assert_not_called()
         self.network_client.availability_zones.assert_not_called()
 
@@ -212,7 +204,7 @@ class TestAvailabilityZoneList(
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.availability_zones.assert_not_called()
+        self.compute_client.availability_zones.assert_not_called()
         self.volume_sdk_client.availability_zones.assert_called_with()
         self.network_client.availability_zones.assert_not_called()
 
@@ -236,7 +228,7 @@ class TestAvailabilityZoneList(
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.availability_zones.assert_not_called()
+        self.compute_client.availability_zones.assert_not_called()
         self.volume_sdk_client.availability_zones.assert_not_called()
         self.network_client.availability_zones.assert_called_with()
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/common/test_command.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_command.py
--- 7.4.0-3/openstackclient/tests/unit/common/test_command.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_command.py	2025-07-07 22:41:56.000000000 +0000
@@ -31,7 +31,7 @@ class TestCommand(test_utils.TestCase):
         cmd = FakeCommand(mock.Mock(), mock.Mock())
         self.assertTrue(hasattr(cmd, 'log'))
         self.assertEqual(
-            'openstackclient.tests.unit.common.test_command.' 'FakeCommand',
+            'openstackclient.tests.unit.common.test_command.FakeCommand',
             cmd.log.name,
         )
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/common/test_extension.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_extension.py
--- 7.4.0-3/openstackclient/tests/unit/common/test_extension.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_extension.py	2025-07-07 22:41:56.000000000 +0000
@@ -52,9 +52,7 @@ class TestExtensionList(TestExtension):
         self.identity_client.extensions.list.return_value = [
             self.identity_extension
         ]
-        self.compute_sdk_client.extensions.return_value = [
-            self.compute_extension
-        ]
+        self.compute_client.extensions.return_value = [self.compute_extension]
         self.volume_sdk_client.extensions.return_value = [
             self.volume_extension
         ]
@@ -106,7 +104,7 @@ class TestExtensionList(TestExtension):
         )
         self._test_extension_list_helper(arglist, verifylist, datalist)
         self.identity_client.extensions.list.assert_called_with()
-        self.compute_sdk_client.extensions.assert_called_with()
+        self.compute_client.extensions.assert_called_with()
         self.volume_sdk_client.extensions.assert_called_with()
         self.network_client.extensions.assert_called_with()
 
@@ -153,7 +151,7 @@ class TestExtensionList(TestExtension):
         )
         self._test_extension_list_helper(arglist, verifylist, datalist, True)
         self.identity_client.extensions.list.assert_called_with()
-        self.compute_sdk_client.extensions.assert_called_with()
+        self.compute_client.extensions.assert_called_with()
         self.volume_sdk_client.extensions.assert_called_with()
         self.network_client.extensions.assert_called_with()
 
@@ -230,7 +228,7 @@ class TestExtensionList(TestExtension):
             ),
         )
         self._test_extension_list_helper(arglist, verifylist, datalist)
-        self.compute_sdk_client.extensions.assert_called_with()
+        self.compute_client.extensions.assert_called_with()
 
     def test_extension_list_compute_and_network(self):
         arglist = [
@@ -254,7 +252,7 @@ class TestExtensionList(TestExtension):
             ),
         )
         self._test_extension_list_helper(arglist, verifylist, datalist)
-        self.compute_sdk_client.extensions.assert_called_with()
+        self.compute_client.extensions.assert_called_with()
         self.network_client.extensions.assert_called_with()
 
     def test_extension_list_volume(self):
diff -pruN 7.4.0-3/openstackclient/tests/unit/common/test_limits.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_limits.py
--- 7.4.0-3/openstackclient/tests/unit/common/test_limits.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_limits.py	2025-07-07 22:41:56.000000000 +0000
@@ -68,7 +68,7 @@ class TestComputeLimits(compute_fakes.Te
             ('DELETE', '*', 100, 100, 'MINUTE', '2011-12-15T22:42:45Z'),
         ]
 
-        self.compute_sdk_client.get_limits.return_value = self.fake_limits
+        self.compute_client.get_limits.return_value = self.fake_limits
 
     def test_compute_show_absolute(self):
         arglist = ['--absolute']
diff -pruN 7.4.0-3/openstackclient/tests/unit/common/test_project_cleanup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_project_cleanup.py
--- 7.4.0-3/openstackclient/tests/unit/common/test_project_cleanup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_project_cleanup.py	2025-07-07 22:41:56.000000000 +0000
@@ -10,7 +10,6 @@
 #   License for the specific language governing permissions and limitations
 #   under the License.
 
-from io import StringIO
 from unittest import mock
 
 from openstackclient.common import project_cleanup
@@ -70,7 +69,7 @@ class TestProjectCleanup(test_utils.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = None
 
-        with mock.patch('sys.stdin', StringIO('y')):
+        with mock.patch('getpass.getpass', return_value='y'):
             result = self.cmd.take_action(parsed_args)
 
         self.sdk_connect_as_project_mock.assert_called_with(self.project)
@@ -143,7 +142,7 @@ class TestProjectCleanup(test_utils.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = None
 
-        with mock.patch('sys.stdin', StringIO('y')):
+        with mock.patch('getpass.getpass', return_value='y'):
             result = self.cmd.take_action(parsed_args)
 
         self.sdk_connect_as_project_mock.assert_called_with(self.project)
@@ -178,7 +177,7 @@ class TestProjectCleanup(test_utils.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = None
 
-        with mock.patch('sys.stdin', StringIO('n')):
+        with mock.patch('getpass.getpass', return_value='y'):
             result = self.cmd.take_action(parsed_args)
 
         self.sdk_connect_as_project_mock.assert_called_with(self.project)
@@ -234,7 +233,7 @@ class TestProjectCleanup(test_utils.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = None
 
-        with mock.patch('sys.stdin', StringIO('y')):
+        with mock.patch('getpass.getpass', return_value='y'):
             result = self.cmd.take_action(parsed_args)
 
         self.sdk_connect_as_project_mock.assert_not_called()
@@ -268,7 +267,7 @@ class TestProjectCleanup(test_utils.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = None
 
-        with mock.patch('sys.stdin', StringIO('y')):
+        with mock.patch('getpass.getpass', return_value='y'):
             result = self.cmd.take_action(parsed_args)
 
         self.sdk_connect_as_project_mock.assert_called_with(self.project)
diff -pruN 7.4.0-3/openstackclient/tests/unit/common/test_quota.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_quota.py
--- 7.4.0-3/openstackclient/tests/unit/common/test_quota.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/common/test_quota.py	2025-07-07 22:41:56.000000000 +0000
@@ -98,7 +98,7 @@ class TestQuotaList(TestQuota):
             _compute_quota_set.QuotaSet
         )
         # the defaults are global hence use of return_value here
-        self.compute_sdk_client.get_quota_set_defaults.return_value = (
+        self.compute_client.get_quota_set_defaults.return_value = (
             self.default_compute_quotas
         )
         self.compute_reference_data = (
@@ -164,7 +164,7 @@ class TestQuotaList(TestQuota):
 
     def test_quota_list_compute(self):
         # Two projects with non-default quotas
-        self.compute_sdk_client.get_quota_set.side_effect = self.compute_quotas
+        self.compute_client.get_quota_set.side_effect = self.compute_quotas
 
         arglist = [
             '--compute',
@@ -183,7 +183,7 @@ class TestQuotaList(TestQuota):
 
     def test_quota_list_compute_default(self):
         # One of the projects is at defaults
-        self.compute_sdk_client.get_quota_set.side_effect = [
+        self.compute_client.get_quota_set.side_effect = [
             self.compute_quotas[0],
             self.default_compute_quotas,
         ]
@@ -205,7 +205,7 @@ class TestQuotaList(TestQuota):
 
     def test_quota_list_compute_project_not_found(self):
         # Make one of the projects disappear
-        self.compute_sdk_client.get_quota_set.side_effect = [
+        self.compute_client.get_quota_set.side_effect = [
             self.compute_quotas[0],
             sdk_exceptions.NotFoundException("NotFound"),
         ]
@@ -227,7 +227,7 @@ class TestQuotaList(TestQuota):
 
     def test_quota_list_compute_project_inaccessible(self):
         # Make one of the projects inaccessible
-        self.compute_sdk_client.get_quota_set.side_effect = [
+        self.compute_client.get_quota_set.side_effect = [
             self.compute_quotas[0],
             sdk_exceptions.ForbiddenException("Forbidden"),
         ]
@@ -249,7 +249,7 @@ class TestQuotaList(TestQuota):
 
     def test_quota_list_compute_server_error(self):
         # Make the server "break"
-        self.compute_sdk_client.get_quota_set.side_effect = (
+        self.compute_client.get_quota_set.side_effect = (
             sdk_exceptions.HttpException("Not implemented?")
         )
 
@@ -470,7 +470,7 @@ class TestQuotaSet(TestQuota):
             'server_group_members': servgroup_members_num,
         }
 
-        self.compute_sdk_client.update_quota_set.assert_called_once_with(
+        self.compute_client.update_quota_set.assert_called_once_with(
             self.projects[0].id, **kwargs
         )
         self.assertIsNone(result)
@@ -744,7 +744,7 @@ class TestQuotaSet(TestQuota):
             'volumes': volumes,
         }
 
-        self.compute_sdk_client.update_quota_class_set.assert_called_with(
+        self.compute_client.update_quota_class_set.assert_called_with(
             self.projects[0].name, **kwargs_compute
         )
         self.volume_sdk_client.update_quota_class_set.assert_called_with(
@@ -842,7 +842,7 @@ class TestQuotaSet(TestQuota):
             'volumes': volumes,
         }
 
-        self.compute_sdk_client.update_quota_class_set.assert_called_with(
+        self.compute_client.update_quota_class_set.assert_called_with(
             'default', **kwargs_compute
         )
         self.volume_sdk_client.update_quota_class_set.assert_called_with(
@@ -899,7 +899,7 @@ class TestQuotaSet(TestQuota):
             'subnet': subnet,
             'force': True,
         }
-        self.compute_sdk_client.update_quota_set.assert_called_once_with(
+        self.compute_client.update_quota_set.assert_called_once_with(
             self.projects[0].id, **kwargs_compute
         )
         self.volume_sdk_client.update_quota_set.assert_called_once_with(
@@ -942,7 +942,7 @@ class TestQuotaSet(TestQuota):
             'subnet': 10,
             'check_limit': True,
         }
-        self.compute_sdk_client.update_quota_set.assert_called_once_with(
+        self.compute_client.update_quota_set.assert_called_once_with(
             self.projects[0].id, **kwargs_compute
         )
         self.volume_sdk_client.update_quota_set.assert_called_once_with(
@@ -955,18 +955,35 @@ class TestQuotaSet(TestQuota):
 
 
 class TestQuotaShow(TestQuota):
+    _network_quota_details = {
+        'floating_ips': {'limit': 0, 'reserved': 0, 'used': 0},
+        'health_monitors': {'limit': 0, 'reserved': 0, 'used': 0},
+        'l7_policies': {'limit': 0, 'reserved': 0, 'used': 0},
+        'listeners': {'limit': 0, 'reserved': 0, 'used': 0},
+        'load_balancers': {'limit': 0, 'reserved': 0, 'used': 0},
+        'networks': {'limit': 0, 'reserved': 0, 'used': 0},
+        'pools': {'limit': 0, 'reserved': 0, 'used': 0},
+        'ports': {'limit': 0, 'reserved': 0, 'used': 0},
+        'rbac_policies': {'limit': 0, 'reserved': 0, 'used': 0},
+        'routers': {'limit': 0, 'reserved': 0, 'used': 0},
+        'security_group_rules': {'limit': 0, 'reserved': 0, 'used': 0},
+        'security_groups': {'limit': 0, 'reserved': 0, 'used': 0},
+        'subnet_pools': {'limit': 0, 'reserved': 0, 'used': 0},
+        'subnets': {'limit': 0, 'reserved': 0, 'used': 0},
+    }
+
     def setUp(self):
         super().setUp()
 
         self.identity_sdk_client.find_project.return_value = self.projects[0]
 
-        self.compute_sdk_client.get_quota_set.return_value = (
+        self.compute_client.get_quota_set.return_value = (
             sdk_fakes.generate_fake_resource(_compute_quota_set.QuotaSet)
         )
         self.default_compute_quotas = sdk_fakes.generate_fake_resource(
             _compute_quota_set.QuotaSet
         )
-        self.compute_sdk_client.get_quota_set_defaults.return_value = (
+        self.compute_client.get_quota_set_defaults.return_value = (
             self.default_compute_quotas
         )
 
@@ -980,9 +997,15 @@ class TestQuotaShow(TestQuota):
             self.default_volume_quotas
         )
 
-        self.network_client.get_quota.return_value = (
-            sdk_fakes.generate_fake_resource(_network_quota_set.Quota)
-        )
+        def get_network_quota_mock(*args, **kwargs):
+            if kwargs.get("details"):
+                return sdk_fakes.generate_fake_resource(
+                    _network_quota_set.QuotaDetails,
+                    **self._network_quota_details,
+                )
+            return sdk_fakes.generate_fake_resource(_network_quota_set.Quota)
+
+        self.network_client.get_quota.side_effect = get_network_quota_mock
         self.default_network_quotas = sdk_fakes.generate_fake_resource(
             _network_quota_set.QuotaDefault
         )
@@ -1004,7 +1027,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set.assert_called_once_with(
+        self.compute_client.get_quota_set.assert_called_once_with(
             self.projects[0].id,
             usage=False,
         )
@@ -1031,7 +1054,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set.assert_called_once_with(
+        self.compute_client.get_quota_set.assert_called_once_with(
             self.projects[0].id,
             usage=False,
         )
@@ -1051,7 +1074,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set.assert_not_called()
+        self.compute_client.get_quota_set.assert_not_called()
         self.volume_sdk_client.get_quota_set.assert_called_once_with(
             self.projects[0].id,
             usage=False,
@@ -1071,7 +1094,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set.assert_not_called()
+        self.compute_client.get_quota_set.assert_not_called()
         self.volume_sdk_client.get_quota_set.assert_not_called()
         self.network_client.get_quota.assert_called_once_with(
             self.projects[0].id,
@@ -1092,7 +1115,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set_defaults.assert_called_once_with(
+        self.compute_client.get_quota_set_defaults.assert_called_once_with(
             self.projects[0].id,
         )
         self.volume_sdk_client.get_quota_set_defaults.assert_called_once_with(
@@ -1116,7 +1139,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set.assert_called_once_with(
+        self.compute_client.get_quota_set.assert_called_once_with(
             self.projects[0].id,
             usage=True,
         )
@@ -1138,7 +1161,7 @@ class TestQuotaShow(TestQuota):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_quota_set.assert_called_once_with(
+        self.compute_client.get_quota_set.assert_called_once_with(
             self.projects[1].id, usage=False
         )
         self.volume_sdk_client.get_quota_set.assert_called_once_with(
@@ -1158,7 +1181,7 @@ class TestQuotaDelete(TestQuota):
 
         self.identity_sdk_client.find_project.return_value = self.projects[0]
 
-        self.compute_sdk_client.revert_quota_set.return_value = None
+        self.compute_client.revert_quota_set.return_value = None
         self.volume_sdk_client.revert_quota_set.return_value = None
         self.network_client.delete_quota.return_value = None
 
@@ -1182,7 +1205,7 @@ class TestQuotaDelete(TestQuota):
         self.identity_sdk_client.find_project.assert_called_once_with(
             self.projects[0].id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_quota_set.assert_called_once_with(
+        self.compute_client.revert_quota_set.assert_called_once_with(
             self.projects[0].id,
         )
         self.volume_sdk_client.revert_quota_set.assert_called_once_with(
@@ -1211,7 +1234,7 @@ class TestQuotaDelete(TestQuota):
         self.identity_sdk_client.find_project.assert_called_once_with(
             self.projects[0].id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_quota_set.assert_called_once_with(
+        self.compute_client.revert_quota_set.assert_called_once_with(
             self.projects[0].id,
         )
         self.volume_sdk_client.revert_quota_set.assert_not_called()
@@ -1236,7 +1259,7 @@ class TestQuotaDelete(TestQuota):
         self.identity_sdk_client.find_project.assert_called_once_with(
             self.projects[0].id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_quota_set.assert_not_called()
+        self.compute_client.revert_quota_set.assert_not_called()
         self.volume_sdk_client.revert_quota_set.assert_called_once_with(
             self.projects[0].id,
         )
@@ -1261,7 +1284,7 @@ class TestQuotaDelete(TestQuota):
         self.identity_sdk_client.find_project.assert_called_once_with(
             self.projects[0].id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_quota_set.assert_not_called()
+        self.compute_client.revert_quota_set.assert_not_called()
         self.volume_sdk_client.revert_quota_set.assert_not_called()
         self.network_client.delete_quota.assert_called_once_with(
             self.projects[0].id,
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/fakes.py	2025-07-07 22:41:56.000000000 +0000
@@ -13,7 +13,6 @@
 #   under the License.
 #
 
-import copy
 import random
 import re
 from unittest import mock
@@ -32,80 +31,19 @@ from openstack.compute.v2 import server_
 from openstack.compute.v2 import server_migration as _server_migration
 from openstack.compute.v2 import volume_attachment as _volume_attachment
 
-from openstackclient.tests.unit import fakes
-from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
+from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 from openstackclient.tests.unit.image.v2 import fakes as image_fakes
 from openstackclient.tests.unit.network.v2 import fakes as network_fakes
 from openstackclient.tests.unit import utils
 from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
 
 
-class FakeComputev2Client:
-    def __init__(self, **kwargs):
-        self.agents = mock.Mock()
-        self.agents.resource_class = fakes.FakeResource(None, {})
-
-        self.images = mock.Mock()
-        self.images.resource_class = fakes.FakeResource(None, {})
-
-        self.servers = mock.Mock()
-        self.servers.resource_class = fakes.FakeResource(None, {})
-
-        self.services = mock.Mock()
-        self.services.resource_class = fakes.FakeResource(None, {})
-
-        self.extensions = mock.Mock()
-        self.extensions.resource_class = fakes.FakeResource(None, {})
-
-        self.flavors = mock.Mock()
-
-        self.flavor_access = mock.Mock()
-        self.flavor_access.resource_class = fakes.FakeResource(None, {})
-
-        self.usage = mock.Mock()
-        self.usage.resource_class = fakes.FakeResource(None, {})
-
-        self.volumes = mock.Mock()
-        self.volumes.resource_class = fakes.FakeResource(None, {})
-
-        self.hypervisors = mock.Mock()
-        self.hypervisors.resource_class = fakes.FakeResource(None, {})
-
-        self.hypervisors_stats = mock.Mock()
-        self.hypervisors_stats.resource_class = fakes.FakeResource(None, {})
-
-        self.keypairs = mock.Mock()
-        self.keypairs.resource_class = fakes.FakeResource(None, {})
-
-        self.server_groups = mock.Mock()
-        self.server_groups.resource_class = fakes.FakeResource(None, {})
-
-        self.server_migrations = mock.Mock()
-        self.server_migrations.resource_class = fakes.FakeResource(None, {})
-
-        self.instance_action = mock.Mock()
-        self.instance_action.resource_class = fakes.FakeResource(None, {})
-
-        self.migrations = mock.Mock()
-        self.migrations.resource_class = fakes.FakeResource(None, {})
-
-        self.auth_token = kwargs['token']
-
-        self.management_url = kwargs['endpoint']
-
-
 class FakeClientMixin:
     def setUp(self):
         super().setUp()
 
-        # TODO(stephenfin): Rename to 'compute_client' once all commands are
-        # migrated to SDK
-        self.app.client_manager.sdk_connection.compute = mock.Mock(
-            _proxy.Proxy
-        )
-        self.compute_sdk_client = (
-            self.app.client_manager.sdk_connection.compute
-        )
+        self.app.client_manager.compute = mock.Mock(_proxy.Proxy)
+        self.compute_client = self.app.client_manager.compute
         self.set_compute_api_version()  # default to the lowest
 
     def set_compute_api_version(self, version: str = '2.1'):
@@ -117,8 +55,8 @@ class FakeClientMixin:
         """
         assert re.match(r'2.\d+', version)
 
-        self.compute_sdk_client.default_microversion = version
-        self.compute_sdk_client.get_endpoint_data.return_value = (
+        self.compute_client.default_microversion = version
+        self.compute_client.get_endpoint_data.return_value = (
             discover.EndpointData(
                 min_microversion='2.1',  # nova has not bumped this yet
                 max_microversion=version,
@@ -127,10 +65,10 @@ class FakeClientMixin:
 
 
 class TestComputev2(
+    identity_fakes.FakeClientMixin,
     network_fakes.FakeClientMixin,
     image_fakes.FakeClientMixin,
     volume_fakes.FakeClientMixin,
-    identity_fakes.FakeClientMixin,
     FakeClientMixin,
     utils.TestCommand,
 ): ...
@@ -139,16 +77,14 @@ class TestComputev2(
 def create_one_agent(attrs=None):
     """Create a fake agent.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with agent_id, os, and so on
+    :param dict attrs: A dictionary with all attributes
+    :return: A dicionarty faking the agent
     """
 
     attrs = attrs or {}
 
     # set default attributes.
-    agent_info = {
+    agent_attrs = {
         'agent_id': 'agent-id-' + uuid.uuid4().hex,
         'os': 'agent-os-' + uuid.uuid4().hex,
         'architecture': 'agent-architecture',
@@ -158,22 +94,20 @@ def create_one_agent(attrs=None):
         'hypervisor': 'hypervisor',
     }
 
+    assert not set(attrs) - set(agent_attrs), 'unknown keys'
+
     # Overwrite default attributes.
-    agent_info.update(attrs)
+    agent_attrs.update(attrs)
 
-    agent = fakes.FakeResource(info=copy.deepcopy(agent_info), loaded=True)
-    return agent
+    return agent_attrs
 
 
 def create_agents(attrs=None, count=2):
     """Create multiple fake agents.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of agents to fake
-    :return:
-        A list of FakeResource objects faking the agents
+    :param dict attrs: A dictionary with all attributes
+    :param int count: The number of agents to fake
+    :return: A list of dictionaries faking the agents
     """
     agents = []
     for i in range(0, count):
@@ -186,7 +120,7 @@ def create_one_extension(attrs=None):
     """Create a fake extension.
 
     :param dict attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.extension.Extension object
+    :return: A fake :class:`~openstack.compute.v2.extension.Extension` object
     """
     attrs = attrs or {}
 
@@ -218,10 +152,8 @@ def create_one_extension(attrs=None):
 def create_one_security_group(attrs=None):
     """Create a fake security group.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with id, name, etc.
+    :param dict attrs: A dictionary with all attributes
+    :return: A dictionary faking the security group
     """
     attrs = attrs or {}
 
@@ -234,6 +166,8 @@ def create_one_security_group(attrs=None
         'rules': [],
     }
 
+    assert not set(attrs) - set(security_group_attrs), 'unknown keys'
+
     # Overwrite default attributes.
     security_group_attrs.update(attrs)
     return security_group_attrs
@@ -242,12 +176,9 @@ def create_one_security_group(attrs=None
 def create_security_groups(attrs=None, count=2):
     """Create multiple fake security groups.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of security groups to fake
-    :return:
-        A list of FakeResource objects faking the security groups
+    :param dict attrs: A dictionary with all attributes
+    :param int count: The number of security groups to fake
+    :return: A list of dictionaries faking the security groups
     """
     security_groups = []
     for i in range(0, count):
@@ -256,32 +187,11 @@ def create_security_groups(attrs=None, c
     return security_groups
 
 
-def get_security_groups(security_groups=None, count=2):
-    """Get an iterable MagicMock with a list of faked security groups.
-
-    If security groups list is provided, then initialize the Mock object
-    with the list. Otherwise create one.
-
-    :param List security_groups:
-        A list of FakeResource objects faking security groups
-    :param int count:
-        The number of security groups to fake
-    :return:
-        An iterable Mock object with side_effect set to a list of faked
-        security groups
-    """
-    if security_groups is None:
-        security_groups = create_security_groups(count)
-    return mock.Mock(side_effect=security_groups)
-
-
 def create_one_security_group_rule(attrs=None):
     """Create a fake security group rule.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with id, etc.
+    :param dict attrs: A dictionary with all attributes
+    :return: A dictionary faking the security group rule
     """
     attrs = attrs or {}
 
@@ -296,6 +206,8 @@ def create_one_security_group_rule(attrs
         'to_port': 0,
     }
 
+    assert not set(attrs) - set(security_group_rule_attrs), 'unknown keys'
+
     # Overwrite default attributes.
     security_group_rule_attrs.update(attrs)
 
@@ -305,12 +217,9 @@ def create_one_security_group_rule(attrs
 def create_security_group_rules(attrs=None, count=2):
     """Create multiple fake security group rules.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of security group rules to fake
-    :return:
-        A list of FakeResource objects faking the security group rules
+    :param dict attrs: A dictionary with all attributes
+    :param int count: The number of security group rules to fake
+    :return: A list of dictionaries faking the security group rules
     """
     security_group_rules = []
     for i in range(0, count):
@@ -319,66 +228,11 @@ def create_security_group_rules(attrs=No
     return security_group_rules
 
 
-def create_one_server(attrs=None, methods=None):
-    """Create a fake server.
-
-    :param dict attrs:
-        A dictionary with all attributes
-    :param dict methods:
-        A dictionary with all methods
-    :return:
-        A FakeResource object, with id, name, metadata, and so on
-    """
-    attrs = attrs or {}
-    methods = methods or {}
-
-    # Set default attributes.
-    server_info = {
-        'id': 'server-id-' + uuid.uuid4().hex,
-        'name': 'server-name-' + uuid.uuid4().hex,
-        'metadata': {},
-        'image': {
-            'id': 'image-id-' + uuid.uuid4().hex,
-        },
-        'flavor': {
-            'id': 'flavor-id-' + uuid.uuid4().hex,
-        },
-        'OS-EXT-STS:power_state': 1,
-    }
-
-    # Overwrite default attributes.
-    server_info.update(attrs)
-
-    server = fakes.FakeResource(
-        info=copy.deepcopy(server_info), methods=methods, loaded=True
-    )
-    return server
-
-
-def create_servers(attrs=None, methods=None, count=2):
-    """Create multiple fake servers.
-
-    :param dict attrs:
-        A dictionary with all attributes
-    :param dict methods:
-        A dictionary with all methods
-    :param int count:
-        The number of servers to fake
-    :return:
-        A list of FakeResource objects faking the servers
-    """
-    servers = []
-    for i in range(0, count):
-        servers.append(create_one_server(attrs, methods))
-
-    return servers
-
-
-def create_one_sdk_server(attrs=None):
-    """Create a fake server for testing migration to sdk
+def create_one_server(attrs=None):
+    """Create a fake server
 
     :param dict attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.server.Server object,
+    :return: A fake :class:`~openstack.compute.v2.server.Server` object,
     """
     attrs = attrs or {}
 
@@ -406,43 +260,26 @@ def create_one_sdk_server(attrs=None):
     return server
 
 
-def create_sdk_servers(attrs=None, count=2):
-    """Create multiple fake servers for testing migration to sdk
+def create_servers(attrs=None, count=2):
+    """Create multiple fake servers
 
     :param dict attrs: A dictionary with all attributes
     :param int count: The number of servers to fake
-    :return: A list of fake openstack.compute.v2.server.Server objects
+    :return: A list of fake :class:`openstack.compute.v2.server.Server` objects
     """
     servers = []
     for i in range(0, count):
-        servers.append(create_one_sdk_server(attrs))
+        servers.append(create_one_server(attrs))
 
     return servers
 
 
-def get_servers(servers=None, count=2):
-    """Get an iterable MagicMock object with a list of faked servers.
-
-    If servers list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param list servers: A list of fake openstack.compute.v2.server.Server
-        objects
-    :param int count:
-        The number of servers to fake
-    :return: An iterable Mock object with side_effect set to a list of faked
-        servers
-    """
-    if servers is None:
-        servers = create_servers(count)
-    return mock.Mock(side_effect=servers)
-
-
 def create_one_server_action(attrs=None):
     """Create a fake server action.
 
     :param attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.server_action.ServerAction object
+    :return: A fake :class:`~openstack.compute.v2.server_action.ServerAction`
+        object
     """
     attrs = attrs or {}
 
@@ -485,7 +322,7 @@ def create_one_flavor(attrs=None):
     """Create a fake flavor.
 
     :param dict attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.flavor.Flavor object
+    :return: A fake :class:`~openstack.compute.v2.flavor.Flavor` object
     """
     attrs = attrs or {}
 
@@ -518,7 +355,7 @@ def create_flavors(attrs=None, count=2):
 
     :param dict attrs: A dictionary with all attributes
     :param int count: The number of flavors to fake
-    :return: A list of fake openstack.compute.v2.flavor.Flavor objects
+    :return: A list of fake :class:`openstack.compute.v2.flavor.Flavor` objects
     """
     flavors = []
     for i in range(0, count):
@@ -527,30 +364,11 @@ def create_flavors(attrs=None, count=2):
     return flavors
 
 
-def get_flavors(flavors=None, count=2):
-    """Get an iterable MagicMock object with a list of faked flavors.
-
-    If flavors list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param list flavors: A list of fake openstack.compute.v2.flavor.Flavor
-        objects
-    :param int count: The number of flavors to fake
-    :return: An iterable Mock object with side_effect set to a list of faked
-        flavors
-    """
-    if flavors is None:
-        flavors = create_flavors(count)
-    return mock.Mock(side_effect=flavors)
-
-
 def create_one_flavor_access(attrs=None):
     """Create a fake flavor access.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with flavor_id, tenat_id
+    :param dict attrs: A dictionary with all attributes
+    :return: A dictionary faking the flavor access
     """
     attrs = attrs or {}
 
@@ -560,22 +378,20 @@ def create_one_flavor_access(attrs=None)
         'tenant_id': 'tenant-id-' + uuid.uuid4().hex,
     }
 
+    assert not set(attrs) - set(flavor_access_info), 'unknown keys'
+
     # Overwrite default attributes.
     flavor_access_info.update(attrs)
 
-    flavor_access = fakes.FakeResource(
-        info=copy.deepcopy(flavor_access_info), loaded=True
-    )
-
-    return flavor_access
+    return flavor_access_info
 
 
 def create_one_availability_zone(attrs=None):
     """Create a fake AZ.
 
     :param dict attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.availability_zone.AvailabilityZone
-        object
+    :return: A fake
+        :class:`~openstack.compute.v2.availability_zone.AvailabilityZone` object
     """
     attrs = attrs or {}
 
@@ -622,12 +438,10 @@ def create_availability_zones(attrs=None
 
 
 def create_one_floating_ip(attrs=None):
-    """Create a fake floating ip.
+    """Create a fake floating IP.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with id, ip, and so on
+    :param dict attrs: A dictionary with all attributes
+    :return: A dictionary faking the floating IP
     """
     attrs = attrs or {}
 
@@ -640,6 +454,8 @@ def create_one_floating_ip(attrs=None):
         'pool': 'public',
     }
 
+    assert not set(attrs) - set(floating_ip_attrs), 'unknown keys'
+
     # Overwrite default attributes.
     floating_ip_attrs.update(attrs)
 
@@ -647,14 +463,11 @@ def create_one_floating_ip(attrs=None):
 
 
 def create_floating_ips(attrs=None, count=2):
-    """Create multiple fake floating ips.
+    """Create multiple fake floating IPs.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of floating ips to fake
-    :return:
-        A list of FakeResource objects faking the floating ips
+    :param dict attrs: A dictionary with all attributes
+    :param int count: The number of floating IPs to fake
+    :return: A list of dictionaries faking the floating IPs
     """
     floating_ips = []
     for i in range(0, count):
@@ -662,32 +475,11 @@ def create_floating_ips(attrs=None, coun
     return floating_ips
 
 
-def get_floating_ips(floating_ips=None, count=2):
-    """Get an iterable MagicMock object with a list of faked floating ips.
-
-    If floating_ips list is provided, then initialize the Mock object
-    with the list. Otherwise create one.
-
-    :param List floating_ips:
-        A list of FakeResource objects faking floating ips
-    :param int count:
-        The number of floating ips to fake
-    :return:
-        An iterable Mock object with side_effect set to a list of faked
-        floating ips
-    """
-    if floating_ips is None:
-        floating_ips = create_floating_ips(count)
-    return mock.Mock(side_effect=floating_ips)
-
-
 def create_one_floating_ip_pool(attrs=None):
-    """Create a fake floating ip pool.
+    """Create a fake floating IP pool.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with name, etc
+    :param dict attrs: A dictionary with all attributes
+    :return: A dictionary faking the floating IP pool
     """
     if attrs is None:
         attrs = {}
@@ -697,6 +489,8 @@ def create_one_floating_ip_pool(attrs=No
         'name': 'floating-ip-pool-name-' + uuid.uuid4().hex,
     }
 
+    assert not set(attrs) - set(floating_ip_pool_attrs), 'unknown keys'
+
     # Overwrite default attributes.
     floating_ip_pool_attrs.update(attrs)
 
@@ -704,14 +498,11 @@ def create_one_floating_ip_pool(attrs=No
 
 
 def create_floating_ip_pools(attrs=None, count=2):
-    """Create multiple fake floating ip pools.
+    """Create multiple fake floating IP pools.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of floating ip pools to fake
-    :return:
-        A list of FakeResource objects faking the floating ip pools
+    :param dict attrs: A dictionary with all attributes
+    :param int count: The number of floating IP pools to fake
+    :return: A list of dictionaries faking the floating IP pools
     """
     floating_ip_pools = []
     for i in range(0, count):
@@ -722,10 +513,8 @@ def create_floating_ip_pools(attrs=None,
 def create_one_network(attrs=None):
     """Create a fake network.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object, with id, label, cidr and so on
+    :param dict attrs: A dictionary with all attributes
+    :return: A dictionary faking the network
     """
     attrs = attrs or {}
 
@@ -765,6 +554,8 @@ def create_one_network(attrs=None):
         'vpn_public_port': None,
     }
 
+    assert not set(attrs) - set(network_attrs), 'unknown keys'
+
     # Overwrite default attributes.
     network_attrs.update(attrs)
 
@@ -774,12 +565,9 @@ def create_one_network(attrs=None):
 def create_networks(attrs=None, count=2):
     """Create multiple fake networks.
 
-    :param dict attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of networks to fake
-    :return:
-        A list of FakeResource objects faking the networks
+    :param dict attrs: A dictionary with all attributes
+    :param int count: The number of networks to fake
+    :return: A list of dictionaries faking the networks
     """
     networks = []
     for i in range(0, count):
@@ -788,25 +576,6 @@ def create_networks(attrs=None, count=2)
     return networks
 
 
-def get_networks(networks=None, count=2):
-    """Get an iterable MagicMock object with a list of faked networks.
-
-    If networks list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List networks:
-        A list of FakeResource objects faking networks
-    :param int count:
-        The number of networks to fake
-    :return:
-        An iterable Mock object with side_effect set to a list of faked
-        networks
-    """
-    if networks is None:
-        networks = create_networks(count=count)
-    return mock.Mock(side_effect=networks)
-
-
 def create_limits(attrs=None):
     """Create a fake limits object."""
     attrs = attrs or {}
@@ -872,7 +641,7 @@ def create_one_migration(attrs=None):
     """Create a fake migration.
 
     :param dict attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.migration.Migration object
+    :return: A fake :class:`~openstack.compute.v2.migration.Migration` object
     """
     attrs = attrs or {}
 
@@ -908,7 +677,7 @@ def create_migrations(attrs=None, count=
 
     :param dict attrs: A dictionary with all attributes
     :param int count: The number of migrations to fake
-    :return: A list of fake openstack.compute.v2.migration.Migration objects
+    :return: A list of fake :class:`openstack.compute.v2.migration.Migration` objects
     """
     migrations = []
     for i in range(0, count):
@@ -921,7 +690,8 @@ def create_one_server_migration(attrs=No
     """Create a fake server migration.
 
     :param dict attrs: A dictionary with all attributes
-    :return A fake openstack.compute.v2.server_migration.ServerMigration object
+    :return: A fake
+        :class:`~openstack.compute.v2.server_migration.ServerMigration` object
     """
     attrs = attrs or {}
 
@@ -977,8 +747,8 @@ def create_one_volume_attachment(attrs=N
     """Create a fake volume attachment.
 
     :param dict attrs: A dictionary with all attributes
-    :return: A fake openstack.compute.v2.volume_attachment.VolumeAttachment
-        object
+    :return: A fake
+        :class:`~openstack.compute.v2.volume_attachment.VolumeAttachment` object
     """
     attrs = attrs or {}
 
@@ -1019,12 +789,12 @@ def create_volume_attachments(attrs=None
 
 
 def create_one_server_interface(attrs=None):
-    """Create a fake SDK ServerInterface.
+    """Create a fake ServerInterface.
 
     :param dict attrs: A dictionary with all attributes
     :param dict methods: A dictionary with all methods
-    :return: A fake openstack.compute.v2.server_interface.ServerInterface
-        object
+    :return: A fake
+        :class:`~openstack.compute.v2.server_interface.ServerInterface` object
     """
     attrs = attrs or {}
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_agent.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_agent.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_agent.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_agent.py	2025-07-07 22:41:56.000000000 +0000
@@ -61,7 +61,7 @@ class TestAgentCreate(compute_fakes.Test
             self._agent['version'],
         )
 
-        self.compute_sdk_client.post.return_value = fakes.FakeResponse(
+        self.compute_client.post.return_value = fakes.FakeResponse(
             data={'agent': self._agent}
         )
         self.cmd = agent.CreateAgent(self.app, None)
@@ -87,7 +87,7 @@ class TestAgentCreate(compute_fakes.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.post.assert_called_with(
+        self.compute_client.post.assert_called_with(
             '/os-agents',
             json={
                 'agent': {
@@ -110,7 +110,7 @@ class TestAgentDelete(compute_fakes.Test
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.delete.return_value = fakes.FakeResponse(
+        self.compute_client.delete.return_value = fakes.FakeResponse(
             status_code=http.HTTPStatus.NO_CONTENT
         )
 
@@ -125,7 +125,7 @@ class TestAgentDelete(compute_fakes.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.delete.assert_called_once_with(
+        self.compute_client.delete.assert_called_once_with(
             '/os-agents/123',
             microversion='2.1',
         )
@@ -143,7 +143,7 @@ class TestAgentDelete(compute_fakes.Test
         calls = [
             mock.call(f'/os-agents/{x}', microversion='2.1') for x in arglist
         ]
-        self.compute_sdk_client.delete.assert_has_calls(calls)
+        self.compute_client.delete.assert_has_calls(calls)
         self.assertIsNone(result)
 
     def test_delete_multiple_agents_exception(self):
@@ -154,7 +154,7 @@ class TestAgentDelete(compute_fakes.Test
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.delete.side_effect = [
+        self.compute_client.delete.side_effect = [
             fakes.FakeResponse(status_code=http.HTTPStatus.NO_CONTENT),
             fakes.FakeResponse(status_code=http.HTTPStatus.NO_CONTENT),
             fakes.FakeResponse(status_code=http.HTTPStatus.NOT_FOUND),
@@ -166,7 +166,7 @@ class TestAgentDelete(compute_fakes.Test
         calls = [
             mock.call(f'/os-agents/{x}', microversion='2.1') for x in arglist
         ]
-        self.compute_sdk_client.delete.assert_has_calls(calls)
+        self.compute_client.delete.assert_has_calls(calls)
 
     def test_agent_delete_no_input(self):
         arglist = []
@@ -208,7 +208,7 @@ class TestAgentList(compute_fakes.TestCo
             for _agent in _agents
         ]
 
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
+        self.compute_client.get.return_value = fakes.FakeResponse(
             data={'agents': _agents},
         )
         self.cmd = agent.ListAgent(self.app, None)
@@ -222,7 +222,7 @@ class TestAgentList(compute_fakes.TestCo
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             '/os-agents',
             microversion='2.1',
         )
@@ -241,7 +241,7 @@ class TestAgentList(compute_fakes.TestCo
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
-        self.compute_sdk_client.get.assert_called_once_with(
+        self.compute_client.get.assert_called_once_with(
             '/os-agents?hypervisor=hypervisor',
             microversion='2.1',
         )
@@ -252,10 +252,10 @@ class TestAgentSet(compute_fakes.TestCom
         super().setUp()
 
         self.agent = _generate_fake_agent()
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
+        self.compute_client.get.return_value = fakes.FakeResponse(
             data={'agents': [self.agent]},
         )
-        self.compute_sdk_client.put.return_value = fakes.FakeResponse()
+        self.compute_client.put.return_value = fakes.FakeResponse()
 
         self.cmd = agent.SetAgent(self.app, None)
 
@@ -269,7 +269,7 @@ class TestAgentSet(compute_fakes.TestCom
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.put.assert_called_once_with(
+        self.compute_client.put.assert_called_once_with(
             f'/os-agents/{self.agent["agent_id"]}',
             json={
                 'para': {
@@ -297,7 +297,7 @@ class TestAgentSet(compute_fakes.TestCom
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.put.assert_called_once_with(
+        self.compute_client.put.assert_called_once_with(
             f'/os-agents/{self.agent["agent_id"]}',
             json={
                 'para': {
@@ -325,7 +325,7 @@ class TestAgentSet(compute_fakes.TestCom
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.put.assert_called_once_with(
+        self.compute_client.put.assert_called_once_with(
             f'/os-agents/{self.agent["agent_id"]}',
             json={
                 'para': {
@@ -353,7 +353,7 @@ class TestAgentSet(compute_fakes.TestCom
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.put.assert_called_once_with(
+        self.compute_client.put.assert_called_once_with(
             f'/os-agents/{self.agent["agent_id"]}',
             json={
                 'para': {
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_aggregate.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_aggregate.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_aggregate.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_aggregate.py	2025-07-07 22:41:56.000000000 +0000
@@ -66,10 +66,8 @@ class TestAggregateAddHost(TestAggregate
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
-        self.compute_sdk_client.add_host_to_aggregate.return_value = (
-            self.fake_ag
-        )
+        self.compute_client.find_aggregate.return_value = self.fake_ag
+        self.compute_client.add_host_to_aggregate.return_value = self.fake_ag
         self.cmd = aggregate.AddAggregateHost(self.app, None)
 
     def test_aggregate_add_host(self):
@@ -83,10 +81,10 @@ class TestAggregateAddHost(TestAggregate
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.add_host_to_aggregate.assert_called_once_with(
+        self.compute_client.add_host_to_aggregate.assert_called_once_with(
             self.fake_ag.id, parsed_args.host
         )
         self.assertEqual(self.columns, columns)
@@ -97,10 +95,8 @@ class TestAggregateCreate(TestAggregate)
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.create_aggregate.return_value = self.fake_ag
-        self.compute_sdk_client.set_aggregate_metadata.return_value = (
-            self.fake_ag
-        )
+        self.compute_client.create_aggregate.return_value = self.fake_ag
+        self.compute_client.set_aggregate_metadata.return_value = self.fake_ag
         self.cmd = aggregate.CreateAggregate(self.app, None)
 
     def test_aggregate_create(self):
@@ -112,7 +108,7 @@ class TestAggregateCreate(TestAggregate)
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_aggregate.assert_called_once_with(
+        self.compute_client.create_aggregate.assert_called_once_with(
             name=parsed_args.name
         )
         self.assertEqual(self.columns, columns)
@@ -131,7 +127,7 @@ class TestAggregateCreate(TestAggregate)
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_aggregate.assert_called_once_with(
+        self.compute_client.create_aggregate.assert_called_once_with(
             name=parsed_args.name, availability_zone=parsed_args.zone
         )
         self.assertEqual(self.columns, columns)
@@ -151,10 +147,10 @@ class TestAggregateCreate(TestAggregate)
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_aggregate.assert_called_once_with(
+        self.compute_client.create_aggregate.assert_called_once_with(
             name=parsed_args.name
         )
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, parsed_args.properties
         )
         self.assertEqual(self.columns, columns)
@@ -169,7 +165,7 @@ class TestAggregateDelete(TestAggregate)
             sdk_fakes.generate_fake_resources(_aggregate.Aggregate, 2)
         )
 
-        self.compute_sdk_client.find_aggregate = mock.Mock(
+        self.compute_client.find_aggregate = mock.Mock(
             side_effect=[self.fake_ags[0], self.fake_ags[1]]
         )
         self.cmd = aggregate.DeleteAggregate(self.app, None)
@@ -181,10 +177,10 @@ class TestAggregateDelete(TestAggregate)
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             self.fake_ags[0].id, ignore_missing=False
         )
-        self.compute_sdk_client.delete_aggregate.assert_called_once_with(
+        self.compute_client.delete_aggregate.assert_called_once_with(
             self.fake_ags[0].id, ignore_missing=False
         )
 
@@ -202,8 +198,8 @@ class TestAggregateDelete(TestAggregate)
         calls = []
         for a in self.fake_ags:
             calls.append(call(a.id, ignore_missing=False))
-        self.compute_sdk_client.find_aggregate.assert_has_calls(calls)
-        self.compute_sdk_client.delete_aggregate.assert_has_calls(calls)
+        self.compute_client.find_aggregate.assert_has_calls(calls)
+        self.compute_client.delete_aggregate.assert_has_calls(calls)
 
     def test_delete_multiple_agggregates_with_exception(self):
         arglist = [
@@ -216,7 +212,7 @@ class TestAggregateDelete(TestAggregate)
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.find_aggregate.side_effect = [
+        self.compute_client.find_aggregate.side_effect = [
             self.fake_ags[0],
             sdk_exceptions.NotFoundException,
         ]
@@ -229,8 +225,8 @@ class TestAggregateDelete(TestAggregate)
         calls = []
         for a in arglist:
             calls.append(call(a, ignore_missing=False))
-        self.compute_sdk_client.find_aggregate.assert_has_calls(calls)
-        self.compute_sdk_client.delete_aggregate.assert_called_with(
+        self.compute_client.find_aggregate.assert_has_calls(calls)
+        self.compute_client.delete_aggregate.assert_called_with(
             self.fake_ags[0].id, ignore_missing=False
         )
 
@@ -239,7 +235,7 @@ class TestAggregateList(TestAggregate):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.aggregates.return_value = [self.fake_ag]
+        self.compute_client.aggregates.return_value = [self.fake_ag]
         self.cmd = aggregate.ListAggregate(self.app, None)
 
     def test_aggregate_list(self):
@@ -333,8 +329,8 @@ class TestAggregateRemoveHost(TestAggreg
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
-        self.compute_sdk_client.remove_host_from_aggregate.return_value = (
+        self.compute_client.find_aggregate.return_value = self.fake_ag
+        self.compute_client.remove_host_from_aggregate.return_value = (
             self.fake_ag
         )
         self.cmd = aggregate.RemoveAggregateHost(self.app, None)
@@ -350,10 +346,10 @@ class TestAggregateRemoveHost(TestAggreg
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.remove_host_from_aggregate.assert_called_once_with(
+        self.compute_client.remove_host_from_aggregate.assert_called_once_with(
             self.fake_ag.id, parsed_args.host
         )
         self.assertEqual(self.columns, columns)
@@ -364,7 +360,7 @@ class TestAggregateSet(TestAggregate):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
+        self.compute_client.find_aggregate.return_value = self.fake_ag
         self.cmd = aggregate.SetAggregate(self.app, None)
 
     def test_aggregate_set_no_option(self):
@@ -377,11 +373,11 @@ class TestAggregateSet(TestAggregate):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.assertNotCalled(self.compute_sdk_client.update_aggregate)
-        self.assertNotCalled(self.compute_sdk_client.set_aggregate_metadata)
+        self.assertNotCalled(self.compute_client.update_aggregate)
+        self.assertNotCalled(self.compute_client.set_aggregate_metadata)
         self.assertIsNone(result)
 
     def test_aggregate_set_with_name(self):
@@ -397,13 +393,13 @@ class TestAggregateSet(TestAggregate):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.update_aggregate.assert_called_once_with(
+        self.compute_client.update_aggregate.assert_called_once_with(
             self.fake_ag.id, name=parsed_args.name
         )
-        self.assertNotCalled(self.compute_sdk_client.set_aggregate_metadata)
+        self.assertNotCalled(self.compute_client.set_aggregate_metadata)
         self.assertIsNone(result)
 
     def test_aggregate_set_with_zone(self):
@@ -419,13 +415,13 @@ class TestAggregateSet(TestAggregate):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.update_aggregate.assert_called_once_with(
+        self.compute_client.update_aggregate.assert_called_once_with(
             self.fake_ag.id, availability_zone=parsed_args.zone
         )
-        self.assertNotCalled(self.compute_sdk_client.set_aggregate_metadata)
+        self.assertNotCalled(self.compute_client.set_aggregate_metadata)
         self.assertIsNone(result)
 
     def test_aggregate_set_with_property(self):
@@ -443,11 +439,11 @@ class TestAggregateSet(TestAggregate):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.assertNotCalled(self.compute_sdk_client.update_aggregate)
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.assertNotCalled(self.compute_client.update_aggregate)
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, parsed_args.properties
         )
         self.assertIsNone(result)
@@ -466,11 +462,11 @@ class TestAggregateSet(TestAggregate):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.assertNotCalled(self.compute_sdk_client.update_aggregate)
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.assertNotCalled(self.compute_client.update_aggregate)
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, {'key1': None, 'key2': 'value2'}
         )
         self.assertIsNone(result)
@@ -486,11 +482,11 @@ class TestAggregateSet(TestAggregate):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.assertNotCalled(self.compute_sdk_client.update_aggregate)
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.assertNotCalled(self.compute_client.update_aggregate)
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, {'key1': None}
         )
         self.assertIsNone(result)
@@ -509,13 +505,13 @@ class TestAggregateSet(TestAggregate):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.update_aggregate.assert_called_once_with(
+        self.compute_client.update_aggregate.assert_called_once_with(
             self.fake_ag.id, availability_zone=parsed_args.zone
         )
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, {'key1': None}
         )
         self.assertIsNone(result)
@@ -538,7 +534,7 @@ class TestAggregateShow(TestAggregate):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
+        self.compute_client.find_aggregate.return_value = self.fake_ag
         self.cmd = aggregate.ShowAggregate(self.app, None)
 
         self.data = (
@@ -563,7 +559,7 @@ class TestAggregateShow(TestAggregate):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
 
@@ -575,7 +571,7 @@ class TestAggregateUnset(TestAggregate):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
+        self.compute_client.find_aggregate.return_value = self.fake_ag
         self.cmd = aggregate.UnsetAggregate(self.app, None)
 
     def test_aggregate_unset(self):
@@ -591,7 +587,7 @@ class TestAggregateUnset(TestAggregate):
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, {'unset_key': None}
         )
         self.assertIsNone(result)
@@ -611,7 +607,7 @@ class TestAggregateUnset(TestAggregate):
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.set_aggregate_metadata.assert_called_once_with(
+        self.compute_client.set_aggregate_metadata.assert_called_once_with(
             self.fake_ag.id, {'unset_key1': None, 'unset_key2': None}
         )
         self.assertIsNone(result)
@@ -626,7 +622,7 @@ class TestAggregateUnset(TestAggregate):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.assertNotCalled(self.compute_sdk_client.set_aggregate_metadata)
+        self.assertNotCalled(self.compute_client.set_aggregate_metadata)
         self.assertIsNone(result)
 
 
@@ -636,7 +632,7 @@ class TestAggregateCacheImage(TestAggreg
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_aggregate.return_value = self.fake_ag
+        self.compute_client.find_aggregate.return_value = self.fake_ag
         self.find_image_mock = mock.Mock(side_effect=self.images)
         self.app.client_manager.sdk_connection.image.find_image = (
             self.find_image_mock
@@ -667,10 +663,10 @@ class TestAggregateCacheImage(TestAggreg
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.aggregate_precache_images.assert_called_once_with(
+        self.compute_client.aggregate_precache_images.assert_called_once_with(
             self.fake_ag.id, [self.images[0].id]
         )
 
@@ -688,9 +684,9 @@ class TestAggregateCacheImage(TestAggreg
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_aggregate.assert_called_once_with(
+        self.compute_client.find_aggregate.assert_called_once_with(
             parsed_args.aggregate, ignore_missing=False
         )
-        self.compute_sdk_client.aggregate_precache_images.assert_called_once_with(
+        self.compute_client.aggregate_precache_images.assert_called_once_with(
             self.fake_ag.id, [self.images[0].id, self.images[1].id]
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_console.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_console.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_console.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_console.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,7 +28,7 @@ class TestConsoleLog(compute_fakes.TestC
         super().setUp()
 
         self._server = sdk_fakes.generate_fake_resource(_server.Server)
-        self.compute_sdk_client.find_server.return_value = self._server
+        self.compute_client.find_server.return_value = self._server
 
         self.cmd = console.ShowConsoleLog(self.app, None)
 
@@ -49,13 +49,13 @@ class TestConsoleLog(compute_fakes.TestC
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         output = {'output': '1st line\n2nd line\n'}
-        self.compute_sdk_client.get_server_console_output.return_value = output
+        self.compute_client.get_server_console_output.return_value = output
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             name_or_id='fake_server', ignore_missing=False
         )
-        self.compute_sdk_client.get_server_console_output.assert_called_with(
+        self.compute_client.get_server_console_output.assert_called_with(
             self._server.id, length=None
         )
         stdout = self.app.stdout.content
@@ -67,13 +67,13 @@ class TestConsoleLog(compute_fakes.TestC
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         output = {'output': '1st line\n2nd line'}
-        self.compute_sdk_client.get_server_console_output.return_value = output
+        self.compute_client.get_server_console_output.return_value = output
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             name_or_id='fake_server', ignore_missing=False
         )
-        self.compute_sdk_client.get_server_console_output.assert_called_with(
+        self.compute_client.get_server_console_output.assert_called_with(
             self._server.id, length=15
         )
 
@@ -83,14 +83,14 @@ class TestConsoleUrlShow(compute_fakes.T
         super().setUp()
 
         self._server = sdk_fakes.generate_fake_resource(_server.Server)
-        self.compute_sdk_client.find_server.return_value = self._server
+        self.compute_client.find_server.return_value = self._server
 
         fake_console_data = {
             'url': 'http://localhost',
             'protocol': 'fake_protocol',
             'type': 'fake_type',
         }
-        self.compute_sdk_client.create_console = mock.Mock(
+        self.compute_client.create_console = mock.Mock(
             return_value=fake_console_data
         )
 
@@ -117,7 +117,7 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='novnc'
         )
         self.assertEqual(self.columns, columns)
@@ -134,7 +134,7 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='novnc'
         )
         self.assertEqual(self.columns, columns)
@@ -151,13 +151,13 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='xvpvnc'
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
 
-    def test_console_url_show_with_spice(self):
+    def test_console_url_show_with_spice_html5(self):
         arglist = [
             '--spice',
             'foo_vm',
@@ -168,12 +168,29 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='spice-html5'
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
 
+    def test_console_url_show_with_spice_direct(self):
+        arglist = [
+            '--spice-direct',
+            'foo_vm',
+        ]
+        verifylist = [
+            ('url_type', 'spice-direct'),
+            ('server', 'foo_vm'),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+        self.compute_client.create_console.assert_called_once_with(
+            self._server.id, console_type='spice-direct'
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+
     def test_console_url_show_with_rdp(self):
         arglist = [
             '--rdp',
@@ -185,7 +202,7 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='rdp-html5'
         )
         self.assertEqual(self.columns, columns)
@@ -202,7 +219,7 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='serial'
         )
         self.assertEqual(self.columns, columns)
@@ -219,7 +236,7 @@ class TestConsoleUrlShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_console.assert_called_once_with(
+        self.compute_client.create_console.assert_called_once_with(
             self._server.id, console_type='webmks'
         )
         self.assertEqual(self.columns, columns)
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_console_connection.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_console_connection.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_console_connection.py	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_console_connection.py	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,72 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import uuid
+
+from openstack.compute.v2 import console_auth_token as _console_auth_token
+from openstack.test import fakes as sdk_fakes
+
+from openstackclient.compute.v2 import console_connection
+from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
+
+
+class TestConsoleTokens(compute_fakes.TestComputev2):
+    def setUp(self):
+        super().setUp()
+
+        self._console_auth_token = sdk_fakes.generate_fake_resource(
+            _console_auth_token.ConsoleAuthToken,
+            host='127.0.0.1',
+            instance_uuid=uuid.uuid4().hex,
+            internal_access_path=None,
+            port=5900,
+            tls_port=5901,
+        )
+        self.compute_client.validate_console_auth_token.return_value = (
+            self._console_auth_token
+        )
+
+        self.columns = (
+            'host',
+            'instance_uuid',
+            'internal_access_path',
+            'port',
+            'tls_port',
+        )
+        self.data = (
+            self._console_auth_token.host,
+            self._console_auth_token.instance_uuid,
+            self._console_auth_token.internal_access_path,
+            self._console_auth_token.port,
+            self._console_auth_token.tls_port,
+        )
+
+        self.cmd = console_connection.ShowConsoleConnectionInformation(
+            self.app, None
+        )
+
+    def test_console_connection_show(self):
+        arglist = [
+            'token',
+        ]
+        verifylist = [
+            ('token', 'token'),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.compute_client.validate_console_auth_token.assert_called_once_with(
+            'token'
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_flavor.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_flavor.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_flavor.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_flavor.py	2025-07-07 22:41:56.000000000 +0000
@@ -86,7 +86,7 @@ class TestFlavorCreate(TestFlavor):
 
         # Return a project
         self.projects_mock.get.return_value = self.project
-        self.compute_sdk_client.create_flavor.return_value = self.flavor
+        self.compute_client.create_flavor.return_value = self.flavor
         self.cmd = flavor.CreateFlavor(self.app, None)
 
     def test_flavor_create_default_options(self):
@@ -109,7 +109,7 @@ class TestFlavorCreate(TestFlavor):
         }
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_flavor.assert_called_once_with(
+        self.compute_client.create_flavor.assert_called_once_with(
             **default_args
         )
 
@@ -180,17 +180,17 @@ class TestFlavorCreate(TestFlavor):
         # convert expected data tuple to list to be able to modify it
         cmp_data = list(self.data)
         cmp_data[7] = format_columns.DictColumn(props)
-        self.compute_sdk_client.create_flavor.return_value = create_flavor
-        self.compute_sdk_client.create_flavor_extra_specs.return_value = (
+        self.compute_client.create_flavor.return_value = create_flavor
+        self.compute_client.create_flavor_extra_specs.return_value = (
             expected_flavor
         )
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_flavor.assert_called_once_with(**args)
-        self.compute_sdk_client.create_flavor_extra_specs.assert_called_once_with(
+        self.compute_client.create_flavor.assert_called_once_with(**args)
+        self.compute_client.create_flavor_extra_specs.assert_called_once_with(
             create_flavor, props
         )
-        self.compute_sdk_client.get_flavor_access.assert_not_called()
+        self.compute_client.get_flavor_access.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(tuple(cmp_data), data)
@@ -265,19 +265,19 @@ class TestFlavorCreate(TestFlavor):
         # convert expected data tuple to list to be able to modify it
         cmp_data = list(self.data_private)
         cmp_data[7] = format_columns.DictColumn(props)
-        self.compute_sdk_client.create_flavor.return_value = create_flavor
-        self.compute_sdk_client.create_flavor_extra_specs.return_value = (
+        self.compute_client.create_flavor.return_value = create_flavor
+        self.compute_client.create_flavor_extra_specs.return_value = (
             expected_flavor
         )
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_flavor.assert_called_once_with(**args)
-        self.compute_sdk_client.flavor_add_tenant_access.assert_called_with(
+        self.compute_client.create_flavor.assert_called_once_with(**args)
+        self.compute_client.flavor_add_tenant_access.assert_called_with(
             self.flavor.id,
             self.project.id,
         )
-        self.compute_sdk_client.create_flavor_extra_specs.assert_called_with(
+        self.compute_client.create_flavor_extra_specs.assert_called_with(
             create_flavor, props
         )
         self.assertEqual(self.columns, columns)
@@ -362,7 +362,7 @@ class TestFlavorCreate(TestFlavor):
             'description': 'fake description',
         }
 
-        self.compute_sdk_client.create_flavor.assert_called_once_with(**args)
+        self.compute_client.create_flavor.assert_called_once_with(**args)
 
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data_private, data)
@@ -400,7 +400,7 @@ class TestFlavorDelete(TestFlavor):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.delete_flavor.return_value = None
+        self.compute_client.delete_flavor.return_value = None
 
         self.cmd = flavor.DeleteFlavor(self.app, None)
 
@@ -411,14 +411,14 @@ class TestFlavorDelete(TestFlavor):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.find_flavor.return_value = self.flavors[0]
+        self.compute_client.find_flavor.return_value = self.flavors[0]
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             self.flavors[0].id, ignore_missing=False
         )
-        self.compute_sdk_client.delete_flavor.assert_called_with(
+        self.compute_client.delete_flavor.assert_called_with(
             self.flavors[0].id
         )
         self.assertIsNone(result)
@@ -433,7 +433,7 @@ class TestFlavorDelete(TestFlavor):
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.find_flavor.side_effect = self.flavors
+        self.compute_client.find_flavor.side_effect = self.flavors
 
         result = self.cmd.take_action(parsed_args)
 
@@ -441,8 +441,8 @@ class TestFlavorDelete(TestFlavor):
             mock.call(i.id, ignore_missing=False) for i in self.flavors
         ]
         delete_calls = [mock.call(i.id) for i in self.flavors]
-        self.compute_sdk_client.find_flavor.assert_has_calls(find_calls)
-        self.compute_sdk_client.delete_flavor.assert_has_calls(delete_calls)
+        self.compute_client.find_flavor.assert_has_calls(find_calls)
+        self.compute_client.delete_flavor.assert_has_calls(delete_calls)
         self.assertIsNone(result)
 
     def test_multi_flavors_delete_with_exception(self):
@@ -453,7 +453,7 @@ class TestFlavorDelete(TestFlavor):
         verifylist = [('flavor', [self.flavors[0].id, 'unexist_flavor'])]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.find_flavor.side_effect = [
+        self.compute_client.find_flavor.side_effect = [
             self.flavors[0],
             sdk_exceptions.ResourceNotFound,
         ]
@@ -469,8 +469,8 @@ class TestFlavorDelete(TestFlavor):
             mock.call('unexist_flavor', ignore_missing=False),
         ]
         delete_calls = [mock.call(self.flavors[0].id)]
-        self.compute_sdk_client.find_flavor.assert_has_calls(find_calls)
-        self.compute_sdk_client.delete_flavor.assert_has_calls(delete_calls)
+        self.compute_client.find_flavor.assert_has_calls(find_calls)
+        self.compute_client.delete_flavor.assert_has_calls(delete_calls)
 
 
 class TestFlavorList(TestFlavor):
@@ -516,7 +516,7 @@ class TestFlavorList(TestFlavor):
             [],
         ]
 
-        self.compute_sdk_client.flavors = self.api_mock
+        self.compute_client.flavors = self.api_mock
 
         # Get the command object to test
         self.cmd = flavor.ListFlavor(self.app, None)
@@ -541,8 +541,8 @@ class TestFlavorList(TestFlavor):
             'is_public': True,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_not_called()
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -567,8 +567,8 @@ class TestFlavorList(TestFlavor):
             'is_public': None,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_not_called()
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -593,8 +593,8 @@ class TestFlavorList(TestFlavor):
             'is_public': False,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_not_called()
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -619,8 +619,8 @@ class TestFlavorList(TestFlavor):
             'is_public': True,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_not_called()
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -645,8 +645,8 @@ class TestFlavorList(TestFlavor):
             'is_public': True,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_not_called()
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_not_called()
 
         self.assertEqual(self.columns_long, columns)
         self.assertCountEqual(self.data_long, tuple(data))
@@ -678,8 +678,8 @@ class TestFlavorList(TestFlavor):
             [],
         ]
 
-        self.compute_sdk_client.flavors = self.api_mock
-        self.compute_sdk_client.fetch_flavor_extra_specs = mock.Mock(
+        self.compute_client.flavors = self.api_mock
+        self.compute_client.fetch_flavor_extra_specs = mock.Mock(
             return_value=None
         )
 
@@ -702,8 +702,8 @@ class TestFlavorList(TestFlavor):
             'is_public': True,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_called_once_with(
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_called_once_with(
             flavor
         )
 
@@ -736,15 +736,15 @@ class TestFlavorList(TestFlavor):
             'min_ram': 2048,
         }
 
-        self.compute_sdk_client.flavors.assert_called_with(**kwargs)
-        self.compute_sdk_client.fetch_flavor_extra_specs.assert_not_called()
+        self.compute_client.flavors.assert_called_with(**kwargs)
+        self.compute_client.fetch_flavor_extra_specs.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
 
 class TestFlavorSet(TestFlavor):
-    # Return value of self.compute_sdk_client.find_flavor().
+    # Return value of self.compute_client.find_flavor().
     flavor = compute_fakes.create_one_flavor(
         attrs={'os-flavor-access:is_public': False}
     )
@@ -753,7 +753,7 @@ class TestFlavorSet(TestFlavor):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
+        self.compute_client.find_flavor.return_value = self.flavor
         # Return a project
         self.projects_mock.get.return_value = self.project
         self.cmd = flavor.SetFlavor(self.app, None)
@@ -767,10 +767,10 @@ class TestFlavorSet(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
-        self.compute_sdk_client.create_flavor_extra_specs.assert_called_with(
+        self.compute_client.create_flavor_extra_specs.assert_called_with(
             self.flavor.id, {'FOO': '"B A R"'}
         )
         self.assertIsNone(result)
@@ -781,10 +781,10 @@ class TestFlavorSet(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
-        self.compute_sdk_client.delete_flavor_extra_specs_property.assert_called_with(
+        self.compute_client.delete_flavor_extra_specs_property.assert_called_with(
             self.flavor.id, 'property'
         )
         self.assertIsNone(result)
@@ -803,14 +803,14 @@ class TestFlavorSet(TestFlavor):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
-        self.compute_sdk_client.flavor_add_tenant_access.assert_called_with(
+        self.compute_client.flavor_add_tenant_access.assert_called_with(
             self.flavor.id,
             self.project.id,
         )
-        self.compute_sdk_client.create_flavor_extra_specs.assert_not_called()
+        self.compute_client.create_flavor_extra_specs.assert_not_called()
         self.assertIsNone(result)
 
     def test_flavor_set_no_project(self):
@@ -847,7 +847,7 @@ class TestFlavorSet(TestFlavor):
         )
 
     def test_flavor_set_with_unexist_flavor(self):
-        self.compute_sdk_client.find_flavor.side_effect = [
+        self.compute_client.find_flavor.side_effect = [
             sdk_exceptions.ResourceNotFound()
         ]
 
@@ -876,10 +876,10 @@ class TestFlavorSet(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
-        self.compute_sdk_client.flavor_add_tenant_access.assert_not_called()
+        self.compute_client.flavor_add_tenant_access.assert_not_called()
         self.assertIsNone(result)
 
     def test_flavor_set_description(self):
@@ -897,7 +897,7 @@ class TestFlavorSet(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.update_flavor.assert_called_with(
+        self.compute_client.update_flavor.assert_called_with(
             flavor=self.flavor.id, description='description'
         )
         self.assertIsNone(result)
@@ -935,7 +935,7 @@ class TestFlavorSet(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.update_flavor.assert_called_with(
+        self.compute_client.update_flavor.assert_called_with(
             flavor=self.flavor.id, description='description'
         )
         self.assertIsNone(result)
@@ -960,7 +960,7 @@ class TestFlavorSet(TestFlavor):
 
 
 class TestFlavorShow(TestFlavor):
-    # Return value of self.compute_sdk_client.find_flavor().
+    # Return value of self.compute_client.find_flavor().
     flavor_access = compute_fakes.create_one_flavor_access()
     flavor = compute_fakes.create_one_flavor()
 
@@ -1000,8 +1000,8 @@ class TestFlavorShow(TestFlavor):
         super().setUp()
 
         # Return value of _find_resource()
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
-        self.compute_sdk_client.get_flavor_access.return_value = [
+        self.compute_client.find_flavor.return_value = self.flavor
+        self.compute_client.get_flavor_access.return_value = [
             self.flavor_access
         ]
         self.cmd = flavor.ShowFlavor(self.app, None)
@@ -1040,7 +1040,7 @@ class TestFlavorShow(TestFlavor):
                 'os-flavor-access:is_public': False,
             }
         )
-        self.compute_sdk_client.find_flavor.return_value = private_flavor
+        self.compute_client.find_flavor.return_value = private_flavor
 
         arglist = [
             private_flavor.name,
@@ -1052,7 +1052,7 @@ class TestFlavorShow(TestFlavor):
         data_with_project = (
             private_flavor.is_disabled,
             private_flavor.ephemeral,
-            [self.flavor_access.tenant_id],
+            [self.flavor_access['tenant_id']],
             private_flavor.description,
             private_flavor.disk,
             private_flavor.id,
@@ -1069,7 +1069,7 @@ class TestFlavorShow(TestFlavor):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_flavor_access.assert_called_with(
+        self.compute_client.get_flavor_access.assert_called_with(
             flavor=private_flavor.id
         )
         self.assertEqual(self.columns, columns)
@@ -1077,7 +1077,7 @@ class TestFlavorShow(TestFlavor):
 
 
 class TestFlavorUnset(TestFlavor):
-    # Return value of self.compute_sdk_client.find_flavor().
+    # Return value of self.compute_client.find_flavor().
     flavor = compute_fakes.create_one_flavor(
         attrs={'os-flavor-access:is_public': False}
     )
@@ -1086,13 +1086,13 @@ class TestFlavorUnset(TestFlavor):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
+        self.compute_client.find_flavor.return_value = self.flavor
         # Return a project
         self.projects_mock.get.return_value = self.project
         self.cmd = flavor.UnsetFlavor(self.app, None)
 
         self.mock_shortcut = (
-            self.compute_sdk_client.delete_flavor_extra_specs_property
+            self.compute_client.delete_flavor_extra_specs_property
         )
 
     def test_flavor_unset_property(self):
@@ -1104,11 +1104,11 @@ class TestFlavorUnset(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
         self.mock_shortcut.assert_called_with(self.flavor.id, 'property')
-        self.compute_sdk_client.flavor_remove_tenant_access.assert_not_called()
+        self.compute_client.flavor_remove_tenant_access.assert_not_called()
         self.assertIsNone(result)
 
     def test_flavor_unset_properties(self):
@@ -1126,7 +1126,7 @@ class TestFlavorUnset(TestFlavor):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
         calls = [
@@ -1141,7 +1141,7 @@ class TestFlavorUnset(TestFlavor):
             AssertionError, self.mock_shortcut.assert_has_calls, calls
         )
 
-        self.compute_sdk_client.flavor_remove_tenant_access.assert_not_called()
+        self.compute_client.flavor_remove_tenant_access.assert_not_called()
 
     def test_flavor_unset_project(self):
         arglist = [
@@ -1158,14 +1158,14 @@ class TestFlavorUnset(TestFlavor):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.find_flavor.assert_called_with(
+        self.compute_client.find_flavor.assert_called_with(
             parsed_args.flavor, get_extra_specs=True, ignore_missing=False
         )
-        self.compute_sdk_client.flavor_remove_tenant_access.assert_called_with(
+        self.compute_client.flavor_remove_tenant_access.assert_called_with(
             self.flavor.id,
             self.project.id,
         )
-        self.compute_sdk_client.delete_flavor_extra_specs_property.assert_not_called()
+        self.compute_client.delete_flavor_extra_specs_property.assert_not_called()
         self.assertIsNone(result)
 
     def test_flavor_unset_no_project(self):
@@ -1202,7 +1202,7 @@ class TestFlavorUnset(TestFlavor):
         )
 
     def test_flavor_unset_with_unexist_flavor(self):
-        self.compute_sdk_client.find_flavor.side_effect = [
+        self.compute_client.find_flavor.side_effect = [
             sdk_exceptions.ResourceNotFound
         ]
 
@@ -1232,4 +1232,4 @@ class TestFlavorUnset(TestFlavor):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.flavor_remove_tenant_access.assert_not_called()
+        self.compute_client.flavor_remove_tenant_access.assert_not_called()
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_host.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_host.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_host.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_host.py	2025-07-07 22:41:56.000000000 +0000
@@ -72,7 +72,7 @@ class TestHostList(compute_fakes.TestCom
             )
         ]
 
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
+        self.compute_client.get.return_value = fakes.FakeResponse(
             data={'hosts': [self._host]}
         )
         self.cmd = host.ListHost(self.app, None)
@@ -85,7 +85,7 @@ class TestHostList(compute_fakes.TestCom
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get.assert_called_with(
+        self.compute_client.get.assert_called_with(
             '/os-hosts', microversion='2.1'
         )
         self.assertEqual(self.columns, columns)
@@ -104,7 +104,7 @@ class TestHostList(compute_fakes.TestCom
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get.assert_called_with(
+        self.compute_client.get.assert_called_with(
             '/os-hosts', microversion='2.1'
         )
         self.assertEqual(self.columns, columns)
@@ -116,7 +116,7 @@ class TestHostSet(compute_fakes.TestComp
         super().setUp()
 
         self._host = _generate_fake_host()
-        self.compute_sdk_client.put.return_value = fakes.FakeResponse()
+        self.compute_client.put.return_value = fakes.FakeResponse()
 
         self.cmd = host.SetHost(self.app, None)
 
@@ -132,7 +132,7 @@ class TestHostSet(compute_fakes.TestComp
 
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
-        self.compute_sdk_client.put.assert_not_called()
+        self.compute_client.put.assert_not_called()
 
     def test_host_set(self):
         arglist = [
@@ -150,7 +150,7 @@ class TestHostSet(compute_fakes.TestComp
 
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
-        self.compute_sdk_client.put.assert_called_with(
+        self.compute_client.put.assert_called_with(
             f'/os-hosts/{self._host["host"]}',
             json={
                 'maintenance_mode': 'disable',
@@ -183,7 +183,7 @@ class TestHostShow(compute_fakes.TestCom
             )
         ]
 
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
+        self.compute_client.get.return_value = fakes.FakeResponse(
             data={
                 'host': [
                     {
@@ -226,7 +226,7 @@ class TestHostShow(compute_fakes.TestCom
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get.assert_called_with(
+        self.compute_client.get.assert_called_with(
             '/os-hosts/' + self._host['host_name'], microversion='2.1'
         )
         self.assertEqual(self.columns, columns)
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_hypervisor.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_hypervisor.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_hypervisor.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_hypervisor.py	2025-07-07 22:41:56.000000000 +0000
@@ -32,9 +32,7 @@ class TestHypervisorList(compute_fakes.T
         self.hypervisors = list(
             sdk_fakes.generate_fake_resources(_hypervisor.Hypervisor, count=2)
         )
-        self.compute_sdk_client.hypervisors.return_value = iter(
-            self.hypervisors
-        )
+        self.compute_client.hypervisors.return_value = iter(self.hypervisors)
 
         self.columns = (
             "ID",
@@ -108,7 +106,7 @@ class TestHypervisorList(compute_fakes.T
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.hypervisors.assert_called_with(details=True)
+        self.compute_client.hypervisors.assert_called_with(details=True)
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
 
@@ -123,9 +121,7 @@ class TestHypervisorList(compute_fakes.T
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         # Fake the return value of search()
-        self.compute_sdk_client.hypervisors.return_value = [
-            self.hypervisors[0]
-        ]
+        self.compute_client.hypervisors.return_value = [self.hypervisors[0]]
 
         self.data = (
             (
@@ -142,7 +138,7 @@ class TestHypervisorList(compute_fakes.T
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.hypervisors.assert_called_with(
+        self.compute_client.hypervisors.assert_called_with(
             hypervisor_hostname_pattern=self.hypervisors[0].name, details=True
         )
         self.assertEqual(self.columns, columns)
@@ -159,9 +155,7 @@ class TestHypervisorList(compute_fakes.T
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         # Fake exception raised from search()
-        self.compute_sdk_client.hypervisors.side_effect = exceptions.NotFound(
-            None
-        )
+        self.compute_client.hypervisors.side_effect = exceptions.NotFound(None)
 
         self.assertRaises(
             exceptions.NotFound, self.cmd.take_action, parsed_args
@@ -205,7 +199,7 @@ class TestHypervisorList(compute_fakes.T
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.hypervisors.assert_called_with(details=True)
+        self.compute_client.hypervisors.assert_called_with(details=True)
         self.assertEqual(self.columns_long, columns)
         self.assertEqual(self.data_long, tuple(data))
 
@@ -223,7 +217,7 @@ class TestHypervisorList(compute_fakes.T
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.hypervisors.assert_called_with(
+        self.compute_client.hypervisors.assert_called_with(
             limit=1, details=True
         )
 
@@ -261,7 +255,7 @@ class TestHypervisorList(compute_fakes.T
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.hypervisors.assert_called_with(
+        self.compute_client.hypervisors.assert_called_with(
             marker='test_hyp', details=True
         )
 
@@ -303,10 +297,10 @@ class TestHypervisorShow(compute_fakes.T
             cpu_info={"aaa": "aaa"},
         )
 
-        self.compute_sdk_client.find_hypervisor.return_value = self.hypervisor
-        self.compute_sdk_client.get_hypervisor.return_value = self.hypervisor
+        self.compute_client.find_hypervisor.return_value = self.hypervisor
+        self.compute_client.get_hypervisor.return_value = self.hypervisor
 
-        self.compute_sdk_client.aggregates.return_value = []
+        self.compute_client.aggregates.return_value = []
 
         uptime_info = {
             'status': self.hypervisor.status,
@@ -315,9 +309,7 @@ class TestHypervisorShow(compute_fakes.T
             'hypervisor_hostname': self.hypervisor.name,
             'uptime': uptime_string,
         }
-        self.compute_sdk_client.get_hypervisor_uptime.return_value = (
-            uptime_info
-        )
+        self.compute_client.get_hypervisor_uptime.return_value = uptime_info
 
         self.columns_v288 = (
             'aggregates',
@@ -434,10 +426,10 @@ class TestHypervisorShow(compute_fakes.T
         self.assertEqual(self.columns_v288, columns)
         self.assertCountEqual(self.data_v288, data)
 
-        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+        self.compute_client.find_hypervisor.assert_called_once_with(
             self.hypervisor.name, ignore_missing=False, details=False
         )
-        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+        self.compute_client.get_hypervisor.assert_called_once_with(
             self.hypervisor.id
         )
 
@@ -460,10 +452,10 @@ class TestHypervisorShow(compute_fakes.T
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
 
-        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+        self.compute_client.find_hypervisor.assert_called_once_with(
             self.hypervisor.name, ignore_missing=False, details=False
         )
-        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+        self.compute_client.get_hypervisor.assert_called_once_with(
             self.hypervisor.id
         )
 
@@ -473,7 +465,7 @@ class TestHypervisorShow(compute_fakes.T
         # before microversion 2.28, nova returned a stringified version of this
         # field
         self.hypervisor.cpu_info = json.dumps(self.hypervisor.cpu_info)
-        self.compute_sdk_client.find_hypervisor.return_value = self.hypervisor
+        self.compute_client.find_hypervisor.return_value = self.hypervisor
 
         arglist = [
             self.hypervisor.name,
@@ -491,10 +483,10 @@ class TestHypervisorShow(compute_fakes.T
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
 
-        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+        self.compute_client.find_hypervisor.assert_called_once_with(
             self.hypervisor.name, ignore_missing=False, details=False
         )
-        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+        self.compute_client.get_hypervisor.assert_called_once_with(
             self.hypervisor.id
         )
 
@@ -509,7 +501,7 @@ class TestHypervisorShow(compute_fakes.T
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.get_hypervisor_uptime.side_effect = (
+        self.compute_client.get_hypervisor_uptime.side_effect = (
             sdk_exceptions.HttpException(http_status=501)
         )
 
@@ -570,9 +562,9 @@ class TestHypervisorShow(compute_fakes.T
         self.assertEqual(expected_columns, columns)
         self.assertCountEqual(expected_data, data)
 
-        self.compute_sdk_client.find_hypervisor.assert_called_once_with(
+        self.compute_client.find_hypervisor.assert_called_once_with(
             self.hypervisor.name, ignore_missing=False, details=False
         )
-        self.compute_sdk_client.get_hypervisor.assert_called_once_with(
+        self.compute_client.get_hypervisor.assert_called_once_with(
             self.hypervisor.id
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py	2025-07-07 22:41:56.000000000 +0000
@@ -23,7 +23,7 @@ class TestHypervisorStats(compute_fakes.
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.get = mock.Mock()
+        self.compute_client.get = mock.Mock()
 
 
 # Not in fakes.py because hypervisor stats has been deprecated
@@ -67,7 +67,7 @@ class TestHypervisorStatsShow(TestHyperv
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.get.return_value = fakes.FakeResponse(
+        self.compute_client.get.return_value = fakes.FakeResponse(
             data={'hypervisor_statistics': self._stats}
         )
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_keypair.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_keypair.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_keypair.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_keypair.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,6 +18,7 @@ import uuid
 
 from openstack.compute.v2 import keypair as _keypair
 from openstack.identity.v3 import project as _project
+from openstack.identity.v3 import role_assignment as _role_assignment
 from openstack.identity.v3 import user as _user
 from openstack.test import fakes as sdk_fakes
 from osc_lib import exceptions
@@ -66,7 +67,7 @@ class TestKeypairCreate(TestKeypair):
         # Get the command object to test
         self.cmd = keypair.CreateKeypair(self.app, None)
 
-        self.compute_sdk_client.create_keypair.return_value = self.keypair
+        self.compute_client.create_keypair.return_value = self.keypair
 
     @mock.patch.object(
         keypair,
@@ -84,7 +85,7 @@ class TestKeypairCreate(TestKeypair):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_keypair.assert_called_with(
+        self.compute_client.create_keypair.assert_called_with(
             name=self.keypair.name,
             public_key=mock_generate.return_value.public_key,
         )
@@ -124,7 +125,7 @@ class TestKeypairCreate(TestKeypair):
 
             columns, data = self.cmd.take_action(parsed_args)
 
-            self.compute_sdk_client.create_keypair.assert_called_with(
+            self.compute_client.create_keypair.assert_called_with(
                 name=self.keypair.name,
                 public_key=self.keypair.public_key,
             )
@@ -159,7 +160,7 @@ class TestKeypairCreate(TestKeypair):
 
             columns, data = self.cmd.take_action(parsed_args)
 
-            self.compute_sdk_client.create_keypair.assert_called_with(
+            self.compute_client.create_keypair.assert_called_with(
                 name=self.keypair.name,
                 public_key=mock_generate.return_value.public_key,
             )
@@ -176,7 +177,7 @@ class TestKeypairCreate(TestKeypair):
         self.set_compute_api_version('2.2')
 
         for key_type in ['x509', 'ssh']:
-            self.compute_sdk_client.create_keypair.return_value = self.keypair
+            self.compute_client.create_keypair.return_value = self.keypair
 
             self.data = (
                 self.keypair.created_at,
@@ -209,7 +210,7 @@ class TestKeypairCreate(TestKeypair):
                 m_file.read.return_value = self.keypair.public_key
                 columns, data = self.cmd.take_action(parsed_args)
 
-            self.compute_sdk_client.create_keypair.assert_called_with(
+            self.compute_client.create_keypair.assert_called_with(
                 name=self.keypair.name,
                 public_key=self.keypair.public_key,
                 key_type=key_type,
@@ -272,7 +273,7 @@ class TestKeypairCreate(TestKeypair):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_keypair.assert_called_with(
+        self.compute_client.create_keypair.assert_called_with(
             name=self.keypair.name,
             user_id=self._user.id,
             public_key=mock_generate.return_value.public_key,
@@ -324,7 +325,7 @@ class TestKeypairDelete(TestKeypair):
         ret = self.cmd.take_action(parsed_args)
 
         self.assertIsNone(ret)
-        self.compute_sdk_client.delete_keypair.assert_called_with(
+        self.compute_client.delete_keypair.assert_called_with(
             self.keypairs[0].name, ignore_missing=False
         )
 
@@ -342,7 +343,7 @@ class TestKeypairDelete(TestKeypair):
         calls = []
         for k in self.keypairs:
             calls.append(call(k.name, ignore_missing=False))
-        self.compute_sdk_client.delete_keypair.assert_has_calls(calls)
+        self.compute_client.delete_keypair.assert_has_calls(calls)
         self.assertIsNone(result)
 
     def test_delete_multiple_keypairs_with_exception(self):
@@ -356,7 +357,7 @@ class TestKeypairDelete(TestKeypair):
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.delete_keypair.side_effect = [
+        self.compute_client.delete_keypair.side_effect = [
             None,
             exceptions.CommandError,
         ]
@@ -369,7 +370,7 @@ class TestKeypairDelete(TestKeypair):
         calls = []
         for k in arglist:
             calls.append(call(k, ignore_missing=False))
-        self.compute_sdk_client.delete_keypair.assert_has_calls(calls)
+        self.compute_client.delete_keypair.assert_has_calls(calls)
 
     def test_keypair_delete_with_user(self):
         self.set_compute_api_version('2.10')
@@ -384,7 +385,7 @@ class TestKeypairDelete(TestKeypair):
         ret = self.cmd.take_action(parsed_args)
 
         self.assertIsNone(ret)
-        self.compute_sdk_client.delete_keypair.assert_called_with(
+        self.compute_client.delete_keypair.assert_called_with(
             self.keypairs[0].name,
             user_id=self._user.id,
             ignore_missing=False,
@@ -415,7 +416,7 @@ class TestKeypairList(TestKeypair):
         self.keypairs = list(
             sdk_fakes.generate_fake_resources(_keypair.Keypair, count=1)
         )
-        self.compute_sdk_client.keypairs.return_value = iter(self.keypairs)
+        self.compute_client.keypairs.return_value = iter(self.keypairs)
 
         # Get the command object to test
         self.cmd = keypair.ListKeypair(self.app, None)
@@ -435,7 +436,7 @@ class TestKeypairList(TestKeypair):
 
         # Set expected values
 
-        self.compute_sdk_client.keypairs.assert_called_with()
+        self.compute_client.keypairs.assert_called_with()
 
         self.assertEqual(('Name', 'Fingerprint'), columns)
         self.assertEqual(
@@ -458,7 +459,7 @@ class TestKeypairList(TestKeypair):
 
         # Set expected values
 
-        self.compute_sdk_client.keypairs.assert_called_with()
+        self.compute_client.keypairs.assert_called_with()
 
         self.assertEqual(('Name', 'Fingerprint', 'Type'), columns)
         self.assertEqual(
@@ -491,7 +492,7 @@ class TestKeypairList(TestKeypair):
         columns, data = self.cmd.take_action(parsed_args)
 
         users_mock.get.assert_called_with(self._user.name)
-        self.compute_sdk_client.keypairs.assert_called_with(
+        self.compute_client.keypairs.assert_called_with(
             user_id=self._user.id,
         )
 
@@ -529,13 +530,17 @@ class TestKeypairList(TestKeypair):
     def test_keypair_list_with_project(self):
         self.set_compute_api_version('2.35')
 
-        projects_mock = self.identity_client.tenants
+        projects_mock = self.identity_client.projects
         projects_mock.reset_mock()
         projects_mock.get.return_value = self._project
 
-        users_mock = self.identity_client.users
-        users_mock.reset_mock()
-        users_mock.list.return_value = [self._user]
+        role_assignments_mock = self.identity_sdk_client.role_assignments
+        role_assignments_mock.reset_mock()
+        assignment = sdk_fakes.generate_fake_resource(
+            _role_assignment.RoleAssignment
+        )
+        assignment.user = self._user
+        role_assignments_mock.return_value = [assignment]
 
         arglist = ['--project', self._project.name]
         verifylist = [('project', self._project.name)]
@@ -544,8 +549,10 @@ class TestKeypairList(TestKeypair):
         columns, data = self.cmd.take_action(parsed_args)
 
         projects_mock.get.assert_called_with(self._project.name)
-        users_mock.list.assert_called_with(tenant_id=self._project.id)
-        self.compute_sdk_client.keypairs.assert_called_with(
+        role_assignments_mock.assert_called_with(
+            scope_project_id=self._project.id
+        )
+        self.compute_client.keypairs.assert_called_with(
             user_id=self._user.id,
         )
 
@@ -605,7 +612,7 @@ class TestKeypairList(TestKeypair):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.keypairs.assert_called_with(limit=1)
+        self.compute_client.keypairs.assert_called_with(limit=1)
 
     def test_keypair_list_with_limit_pre_v235(self):
         self.set_compute_api_version('2.34')
@@ -641,7 +648,7 @@ class TestKeypairList(TestKeypair):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.keypairs.assert_called_with(marker='test_kp')
+        self.compute_client.keypairs.assert_called_with(marker='test_kp')
 
     def test_keypair_list_with_marker_pre_v235(self):
         self.set_compute_api_version('2.34')
@@ -696,7 +703,7 @@ class TestKeypairShow(TestKeypair):
 
     def test_keypair_show(self):
         self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
-        self.compute_sdk_client.find_keypair.return_value = self.keypair
+        self.compute_client.find_keypair.return_value = self.keypair
 
         self.data = (
             self.keypair.created_at,
@@ -715,7 +722,7 @@ class TestKeypairShow(TestKeypair):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_keypair.assert_called_with(
+        self.compute_client.find_keypair.assert_called_with(
             self.keypair.name, ignore_missing=False
         )
 
@@ -724,7 +731,7 @@ class TestKeypairShow(TestKeypair):
 
     def test_keypair_show_public(self):
         self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
-        self.compute_sdk_client.find_keypair.return_value = self.keypair
+        self.compute_client.find_keypair.return_value = self.keypair
 
         arglist = ['--public-key', self.keypair.name]
         verifylist = [('public_key', True), ('name', self.keypair.name)]
@@ -740,7 +747,7 @@ class TestKeypairShow(TestKeypair):
         self.set_compute_api_version('2.10')
 
         self.keypair = sdk_fakes.generate_fake_resource(_keypair.Keypair)
-        self.compute_sdk_client.find_keypair.return_value = self.keypair
+        self.compute_client.find_keypair.return_value = self.keypair
 
         self.data = (
             self.keypair.created_at,
@@ -767,7 +774,7 @@ class TestKeypairShow(TestKeypair):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.users_mock.get.assert_called_with(self._user.name)
-        self.compute_sdk_client.find_keypair.assert_called_with(
+        self.compute_client.find_keypair.assert_called_with(
             self.keypair.name,
             ignore_missing=False,
             user_id=self._user.id,
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server.py	2025-07-07 22:41:56.000000000 +0000
@@ -21,6 +21,7 @@ from unittest import mock
 import uuid
 
 import iso8601
+from openstack.compute.v2 import server as _server
 from openstack.compute.v2 import server_group as _server_group
 from openstack import exceptions as sdk_exceptions
 from openstack.test import fakes as sdk_fakes
@@ -70,13 +71,13 @@ class TestServer(compute_fakes.TestCompu
         self.attrs = {}
 
     def setup_sdk_servers_mock(self, count):
-        servers = compute_fakes.create_sdk_servers(
+        servers = compute_fakes.create_servers(
             attrs=self.attrs,
             count=count,
         )
 
         # This is the return value for compute_client.find_server()
-        self.compute_sdk_client.find_server.side_effect = servers
+        self.compute_client.find_server.side_effect = servers
 
         return servers
 
@@ -132,9 +133,7 @@ class TestServerAddFixedIP(TestServer):
         servers = self.setup_sdk_servers_mock(count=1)
         network = compute_fakes.create_one_network()
         interface = compute_fakes.create_one_server_interface()
-        self.compute_sdk_client.create_server_interface.return_value = (
-            interface
-        )
+        self.compute_client.create_server_interface.return_value = interface
 
         with mock.patch.object(
             self.app.client_manager,
@@ -169,7 +168,7 @@ class TestServerAddFixedIP(TestServer):
 
             self.assertEqual(expected_columns, columns)
             self.assertEqual(expected_data, tuple(data))
-            self.compute_sdk_client.create_server_interface.assert_called_once_with(
+            self.compute_client.create_server_interface.assert_called_once_with(
                 servers[0].id, net_id=network['id']
             )
 
@@ -179,9 +178,7 @@ class TestServerAddFixedIP(TestServer):
         servers = self.setup_sdk_servers_mock(count=1)
         network = compute_fakes.create_one_network()
         interface = compute_fakes.create_one_server_interface()
-        self.compute_sdk_client.create_server_interface.return_value = (
-            interface
-        )
+        self.compute_client.create_server_interface.return_value = interface
 
         with mock.patch.object(
             self.app.client_manager,
@@ -222,7 +219,7 @@ class TestServerAddFixedIP(TestServer):
 
             self.assertEqual(expected_columns, columns)
             self.assertEqual(expected_data, tuple(data))
-            self.compute_sdk_client.create_server_interface.assert_called_once_with(
+            self.compute_client.create_server_interface.assert_called_once_with(
                 servers[0].id,
                 net_id=network['id'],
                 fixed_ips=[{'ip_address': '5.6.7.8'}],
@@ -234,9 +231,7 @@ class TestServerAddFixedIP(TestServer):
         servers = self.setup_sdk_servers_mock(count=1)
         network = compute_fakes.create_one_network()
         interface = compute_fakes.create_one_server_interface()
-        self.compute_sdk_client.create_server_interface.return_value = (
-            interface
-        )
+        self.compute_client.create_server_interface.return_value = interface
 
         with mock.patch.object(
             self.app.client_manager,
@@ -282,7 +277,7 @@ class TestServerAddFixedIP(TestServer):
 
             self.assertEqual(expected_columns, columns)
             self.assertEqual(expected_data, tuple(data))
-            self.compute_sdk_client.create_server_interface.assert_called_once_with(
+            self.compute_client.create_server_interface.assert_called_once_with(
                 servers[0].id,
                 net_id=network['id'],
                 fixed_ips=[{'ip_address': '5.6.7.8'}],
@@ -295,9 +290,7 @@ class TestServerAddFixedIP(TestServer):
         servers = self.setup_sdk_servers_mock(count=1)
         network = compute_fakes.create_one_network()
         interface = compute_fakes.create_one_server_interface()
-        self.compute_sdk_client.create_server_interface.return_value = (
-            interface
-        )
+        self.compute_client.create_server_interface.return_value = interface
 
         with mock.patch.object(
             self.app.client_manager,
@@ -343,7 +336,7 @@ class TestServerAddFixedIP(TestServer):
 
             self.assertEqual(expected_columns, columns)
             self.assertEqual(expected_data, tuple(data))
-            self.compute_sdk_client.create_server_interface.assert_called_once_with(
+            self.compute_client.create_server_interface.assert_called_once_with(
                 servers[0].id,
                 net_id=network['id'],
                 fixed_ips=[{'ip_address': '5.6.7.8'}],
@@ -356,8 +349,8 @@ class TestServerAddFloatingIPCompute(com
         super().setUp()
 
         self.app.client_manager.network_endpoint_enabled = False
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.cmd = server.AddFloatingIP(self.app, None)
 
@@ -374,10 +367,10 @@ class TestServerAddFloatingIPCompute(com
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False
         )
-        self.compute_sdk_client.add_floating_ip_to_server.assert_called_once_with(
+        self.compute_client.add_floating_ip_to_server.assert_called_once_with(
             self.server, '1.2.3.4', fixed_address=None
         )
 
@@ -397,10 +390,10 @@ class TestServerAddFloatingIPCompute(com
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False
         )
-        self.compute_sdk_client.add_floating_ip_to_server.assert_called_once_with(
+        self.compute_client.add_floating_ip_to_server.assert_called_once_with(
             self.server, '1.2.3.4', fixed_address='5.6.7.8'
         )
 
@@ -412,8 +405,8 @@ class TestServerAddFloatingIPNetwork(
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.network_client.update_ip = mock.Mock(return_value=None)
 
@@ -637,7 +630,7 @@ class TestServerAddPort(TestServer):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server_interface.assert_called_once_with(
+        self.compute_client.create_server_interface.assert_called_once_with(
             servers[0], port_id=port_id
         )
         self.assertIsNone(result)
@@ -674,7 +667,7 @@ class TestServerAddPort(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.create_server_interface.assert_called_once_with(
+        self.compute_client.create_server_interface.assert_called_once_with(
             servers[0], port_id='fake-port', tag='tag1'
         )
 
@@ -708,8 +701,8 @@ class TestServerVolume(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.volume = volume_fakes.create_one_sdk_volume()
         self.volume_sdk_client.find_volume.return_value = self.volume
@@ -722,7 +715,7 @@ class TestServerVolume(TestServer):
             attrs=attrs
         )
 
-        self.compute_sdk_client.create_volume_attachment.return_value = (
+        self.compute_client.create_volume_attachment.return_value = (
             self.volume_attachment
         )
 
@@ -762,7 +755,7 @@ class TestServerAddVolume(TestServerVolu
 
         self.assertEqual(expected_columns, columns)
         self.assertEqual(expected_data, data)
-        self.compute_sdk_client.create_volume_attachment.assert_called_once_with(
+        self.compute_client.create_volume_attachment.assert_called_once_with(
             self.server, volumeId=self.volume.id, device='/dev/sdb'
         )
 
@@ -799,7 +792,7 @@ class TestServerAddVolume(TestServerVolu
 
         self.assertEqual(expected_columns, columns)
         self.assertEqual(expected_data, data)
-        self.compute_sdk_client.create_volume_attachment.assert_called_once_with(
+        self.compute_client.create_volume_attachment.assert_called_once_with(
             self.server,
             volumeId=self.volume.id,
             device='/dev/sdb',
@@ -869,7 +862,7 @@ class TestServerAddVolume(TestServerVolu
         columns, data = self.cmd.take_action(parsed_args)
         self.assertEqual(expected_columns, columns)
         self.assertEqual(expected_data, data)
-        self.compute_sdk_client.create_volume_attachment.assert_called_once_with(
+        self.compute_client.create_volume_attachment.assert_called_once_with(
             self.server,
             volumeId=self.volume.id,
             device='/dev/sdb',
@@ -918,7 +911,7 @@ class TestServerAddVolume(TestServerVolu
 
         self.assertEqual(expected_columns, columns)
         self.assertEqual(expected_data, data)
-        self.compute_sdk_client.create_volume_attachment.assert_called_once_with(
+        self.compute_client.create_volume_attachment.assert_called_once_with(
             self.server,
             volumeId=self.volume.id,
             device='/dev/sdb',
@@ -1031,7 +1024,7 @@ class TestServerRemoveVolume(TestServerV
         result = self.cmd.take_action(parsed_args)
 
         self.assertIsNone(result)
-        self.compute_sdk_client.delete_volume_attachment.assert_called_once_with(
+        self.compute_client.delete_volume_attachment.assert_called_once_with(
             self.volume,
             self.server,
             ignore_missing=False,
@@ -1061,7 +1054,7 @@ class TestServerAddNetwork(TestServer):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server_interface.assert_called_once_with(
+        self.compute_client.create_server_interface.assert_called_once_with(
             servers[0], net_id=net_id
         )
         self.assertIsNone(result)
@@ -1099,7 +1092,7 @@ class TestServerAddNetwork(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.create_server_interface.assert_called_once_with(
+        self.compute_client.create_server_interface.assert_called_once_with(
             servers[0], net_id='fake-network', tag='tag1'
         )
 
@@ -1134,11 +1127,9 @@ class TestServerAddSecurityGroup(compute
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.add_security_group_to_server.return_value = (
-            None
-        )
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.add_security_group_to_server.return_value = None
 
         # Get the command object to test
         self.cmd = server.AddServerSecurityGroup(self.app, None)
@@ -1163,14 +1154,14 @@ class TestServerAddSecurityGroup(compute
             ) as mock_find_nova_net_sg:
                 result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.add_security_group_to_server.assert_called_once_with(
+        self.compute_client.add_security_group_to_server.assert_called_once_with(
             self.server, {'name': 'fake_sg'}
         )
         mock_find_nova_net_sg.assert_called_once_with(
-            self.compute_sdk_client, 'fake_sg'
+            self.compute_client, 'fake_sg'
         )
         self.assertIsNone(result)
 
@@ -1184,10 +1175,10 @@ class TestServerAddSecurityGroup(compute
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.add_security_group_to_server.assert_called_once_with(
+        self.compute_client.add_security_group_to_server.assert_called_once_with(
             self.server, {'name': 'fake_sg'}
         )
         self.assertIsNone(result)
@@ -1297,7 +1288,7 @@ class TestServerCreate(TestServer):
         self.image_client.get_image.return_value = self.image
 
         self.flavor = compute_fakes.create_one_flavor()
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
+        self.compute_client.find_flavor.return_value = self.flavor
 
         attrs = {
             'addresses': {},
@@ -1305,10 +1296,10 @@ class TestServerCreate(TestServer):
             'image': self.image,
             'flavor': self.flavor,
         }
-        self.server = compute_fakes.create_one_sdk_server(attrs=attrs)
+        self.server = compute_fakes.create_one_server(attrs=attrs)
 
-        self.compute_sdk_client.create_server.return_value = self.server
-        self.compute_sdk_client.get_server.return_value = self.server
+        self.compute_client.create_server.return_value = self.server
+        self.compute_client.get_server.return_value = self.server
 
         self.volume = volume_fakes.create_one_volume()
         self.snapshot = volume_fakes.create_one_snapshot()
@@ -1350,13 +1341,13 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_has_calls(
+        self.compute_client.find_flavor.assert_has_calls(
             [mock.call(self.flavor.id, ignore_missing=False)] * 2
         )
         self.image_client.find_image.assert_called_once_with(
             self.image.id, ignore_missing=False
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1380,7 +1371,7 @@ class TestServerCreate(TestServer):
         server_group = sdk_fakes.generate_fake_resource(
             _server_group.ServerGroup
         )
-        self.compute_sdk_client.find_server_group.return_value = server_group
+        self.compute_client.find_server_group.return_value = server_group
 
         security_group = network_fakes.create_one_security_group()
         self.network_client.find_security_group.return_value = security_group
@@ -1423,7 +1414,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_has_calls(
+        self.compute_client.find_flavor.assert_has_calls(
             [mock.call(self.flavor.id, ignore_missing=False)] * 2
         )
         self.network_client.find_security_group.assert_called_once_with(
@@ -1432,10 +1423,10 @@ class TestServerCreate(TestServer):
         self.image_client.find_image.assert_called_once_with(
             self.image.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_server_group.assert_called_once_with(
+        self.compute_client.find_server_group.assert_called_once_with(
             server_group.id, ignore_missing=False
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1525,8 +1516,8 @@ class TestServerCreate(TestServer):
             ) as mock_find:
                 columns, data = self.cmd.take_action(parsed_args)
 
-        mock_find.assert_called_once_with(self.compute_sdk_client, sg_name)
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        mock_find.assert_called_once_with(self.compute_client, sg_name)
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1573,14 +1564,14 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_has_calls(
+        self.compute_client.find_flavor.assert_has_calls(
             [mock.call(self.flavor.id, ignore_missing=False)] * 2
         )
         self.network_client.find_security_group.assert_not_called()
         self.image_client.find_image.assert_called_once_with(
             self.image.id, ignore_missing=False
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1702,7 +1693,7 @@ class TestServerCreate(TestServer):
                 mock.call(port_port2.id, ignore_missing=False),
             ]
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1714,7 +1705,7 @@ class TestServerCreate(TestServer):
                 },
                 {
                     'uuid': network_net2.id,
-                    'fixed': '10.0.0.2',
+                    'fixed_ip': '10.0.0.2',
                 },
                 {
                     'port': port_port1.id,
@@ -1778,7 +1769,7 @@ class TestServerCreate(TestServer):
         self.network_client.find_network.assert_called_once_with(
             network.id, ignore_missing=False
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1839,7 +1830,7 @@ class TestServerCreate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
         self.network_client.find_network.assert_not_called()
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def _test_server_create_with_auto_network(self, arglist):
         # requires API microversion 2.37 or later
@@ -1857,7 +1848,7 @@ class TestServerCreate(TestServer):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.network_client.find_network.assert_not_called()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -1937,7 +1928,7 @@ class TestServerCreate(TestServer):
             'allocation',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_auto_network_default(self):
         """Tests creating a server without specifying --nic using 2.37."""
@@ -1963,7 +1954,7 @@ class TestServerCreate(TestServer):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.network_client.find_network.assert_not_called()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2000,7 +1991,7 @@ class TestServerCreate(TestServer):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.network_client.find_network.assert_not_called()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2080,7 +2071,7 @@ class TestServerCreate(TestServer):
             'allocation',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_conflicting_network_options(self):
         arglist = [
@@ -2125,7 +2116,7 @@ class TestServerCreate(TestServer):
             'other --nic, --network or --port value.',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_invalid_network_options(self):
         arglist = [
@@ -2148,7 +2139,7 @@ class TestServerCreate(TestServer):
             'Invalid argument abcdefgh; argument must be of form ',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_invalid_network_key(self):
         arglist = [
@@ -2171,7 +2162,7 @@ class TestServerCreate(TestServer):
             'Invalid argument abcdefgh=12324; argument must be of form ',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_empty_network_key_value(self):
         arglist = [
@@ -2194,7 +2185,7 @@ class TestServerCreate(TestServer):
             'Invalid argument net-id=; argument must be of form ',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_only_network_key(self):
         arglist = [
@@ -2217,7 +2208,7 @@ class TestServerCreate(TestServer):
             'Invalid argument net-id; argument must be of form ',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_network_in_nova_network(self):
         net_name = 'nova-net-net'
@@ -2263,8 +2254,8 @@ class TestServerCreate(TestServer):
             ) as mock_find:
                 columns, data = self.cmd.take_action(parsed_args)
 
-        mock_find.assert_called_once_with(self.compute_sdk_client, net_name)
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        mock_find.assert_called_once_with(self.compute_client, net_name)
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2307,7 +2298,7 @@ class TestServerCreate(TestServer):
             [],
         )
         self.assertIn("either 'network' or 'port'", str(exc))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_conflicting_fixed_ip_filters(self):
         arglist = [
@@ -2327,7 +2318,7 @@ class TestServerCreate(TestServer):
             [],
         )
         self.assertIn("either 'v4-fixed-ip' or 'v6-fixed-ip'", str(exc))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
     def test_server_create_with_wait_ok(self, mock_wait_for_status):
@@ -2350,7 +2341,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2368,7 +2359,7 @@ class TestServerCreate(TestServer):
             ],
         )
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
         )
@@ -2399,7 +2390,7 @@ class TestServerCreate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2417,7 +2408,7 @@ class TestServerCreate(TestServer):
             ],
         )
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
         )
@@ -2449,7 +2440,7 @@ class TestServerCreate(TestServer):
             columns, data = self.cmd.take_action(parsed_args)
 
         mock_file.assert_called_with('userdata.sh', 'rb')
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2493,7 +2484,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volumes.get.assert_called_once_with(
             self.volume.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id='',
             flavor_id=self.flavor.id,
@@ -2535,7 +2526,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volume_snapshots.get.assert_called_once_with(
             self.snapshot.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id='',
             flavor_id=self.flavor.id,
@@ -2586,7 +2577,7 @@ class TestServerCreate(TestServer):
 
         # we don't do any validation of IDs when using the legacy option
         self.volume_client.volumes.get.assert_not_called()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id='',
             flavor_id=self.flavor.id,
@@ -2664,7 +2655,7 @@ class TestServerCreate(TestServer):
 
         # we don't do any validation of IDs when using the legacy option
         self.volume_client.volumes.get.assert_not_called()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2746,7 +2737,7 @@ class TestServerCreate(TestServer):
 
         # we don't do any validation of IDs when using the legacy option
         self.volume_client.volumes.get.assert_not_called()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -2799,7 +2790,7 @@ class TestServerCreate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
         self.assertIn('The boot_index key of --block-device ', str(ex))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_invalid_source_type(self):
         block_device = f'uuid={self.volume.name},source_type=foo'
@@ -2817,7 +2808,7 @@ class TestServerCreate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
         self.assertIn('The source_type key of --block-device ', str(ex))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_invalid_destination_type(self):
         block_device = f'uuid={self.volume.name},destination_type=foo'
@@ -2835,7 +2826,7 @@ class TestServerCreate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
         self.assertIn('The destination_type key of --block-device ', str(ex))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_invalid_shutdown(self):
         block_device = f'uuid={self.volume.name},delete_on_termination=foo'
@@ -2855,7 +2846,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             'The delete_on_termination key of --block-device ', str(ex)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_tag_pre_v242(self):
         self.set_compute_api_version('2.41')
@@ -2877,7 +2868,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.42 or greater is required', str(ex)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_volume_type_pre_v267(self):
         self.set_compute_api_version('2.66')
@@ -2899,7 +2890,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.67 or greater is required', str(ex)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_mapping(self):
         self.volume_client.volumes.get.return_value = self.volume
@@ -2938,7 +2929,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volumes.get.assert_called_once_with(
             self.volume.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3002,7 +2993,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volumes.get.assert_called_once_with(
             self.volume.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3065,7 +3056,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volumes.get.assert_called_once_with(
             self.volume.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3130,7 +3121,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volumes.get.assert_called_once_with(
             self.volume.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3198,7 +3189,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volume_snapshots.get.assert_called_once_with(
             self.snapshot.name
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3273,7 +3264,7 @@ class TestServerCreate(TestServer):
         self.volume_client.volumes.get.assert_has_calls(
             [mock.call(self.volume.name)] * 2
         )
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3329,7 +3320,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             'argument --block-device-mapping: Invalid argument ', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
         # block device mapping don't contain device name "=uuid:::true"
         arglist = [
@@ -3351,7 +3342,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             'argument --block-device-mapping: Invalid argument ', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_block_device_mapping_no_uuid(self):
         arglist = [
@@ -3373,7 +3364,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             'argument --block-device-mapping: Invalid argument ', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_volume_boot_from_volume_conflict(self):
         # Tests that specifying --volume and --boot-from-volume results in
@@ -3406,7 +3397,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--volume is not allowed with --boot-from-volume', str(ex)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_boot_from_volume_no_image(self):
         # Test --boot-from-volume option without --image or
@@ -3434,7 +3425,7 @@ class TestServerCreate(TestServer):
             'to support --boot-from-volume option',
             str(ex),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_image_property(self):
         image = image_fakes.create_one_image({'hypervisor_type': 'qemu'})
@@ -3458,7 +3449,7 @@ class TestServerCreate(TestServer):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.image_client.images.assert_called_once_with()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=image.id,
             flavor_id=self.flavor.id,
@@ -3508,7 +3499,7 @@ class TestServerCreate(TestServer):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.image_client.images.assert_called_once_with()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=image.id,
             flavor_id=self.flavor.id,
@@ -3563,7 +3554,7 @@ class TestServerCreate(TestServer):
             'No images match the property expected by --image-property',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_image_property_with_image_list(self):
         target_image = image_fakes.create_one_image(
@@ -3596,7 +3587,7 @@ class TestServerCreate(TestServer):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.image_client.images.assert_called_once_with()
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=target_image.id,
             flavor_id=self.flavor.id,
@@ -3652,7 +3643,7 @@ class TestServerCreate(TestServer):
             '(--volume, --snapshot, --block-device) is required',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_swap(self):
         arglist = [
@@ -3674,7 +3665,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3723,7 +3714,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3770,7 +3761,7 @@ class TestServerCreate(TestServer):
             [],
         )
         self.assertIn('Argument parse failed', str(exc))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_ephemeral_invalid_key(self):
         arglist = [
@@ -3790,7 +3781,7 @@ class TestServerCreate(TestServer):
             [],
         )
         self.assertIn('Argument parse failed', str(exc))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_invalid_hint(self):
         # Not a key-value pair
@@ -3811,7 +3802,7 @@ class TestServerCreate(TestServer):
             [],
         )
         self.assertIn('Argument parse failed', str(exc))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
         # Empty key
         arglist = [
@@ -3831,7 +3822,7 @@ class TestServerCreate(TestServer):
             [],
         )
         self.assertIn('Argument parse failed', str(exc))
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_description(self):
         # Description is supported for nova api version 2.19 or above
@@ -3857,7 +3848,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3904,7 +3895,7 @@ class TestServerCreate(TestServer):
         self.assertRaises(
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_tag(self):
         self.set_compute_api_version('2.52')
@@ -3931,7 +3922,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -3982,7 +3973,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.52 or greater is required', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_host(self):
         # Explicit host is supported for nova api version 2.74 or above
@@ -4008,7 +3999,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -4057,7 +4048,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.74 or greater is required', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_hypervisor_hostname(self):
         # Explicit hypervisor_hostname is supported for nova api version
@@ -4084,7 +4075,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -4133,7 +4124,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.74 or greater is required', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_hostname(self):
         self.set_compute_api_version('2.90')
@@ -4158,7 +4149,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -4206,7 +4197,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.90 or greater is required', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_trusted_image_cert(self):
         self.set_compute_api_version('2.63')
@@ -4233,7 +4224,7 @@ class TestServerCreate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server.assert_called_once_with(
+        self.compute_client.create_server.assert_called_once_with(
             name=self.server.name,
             image_id=self.image.id,
             flavor_id=self.flavor.id,
@@ -4283,7 +4274,7 @@ class TestServerCreate(TestServer):
         self.assertIn(
             '--os-compute-api-version 2.63 or greater is required', str(exc)
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_trusted_image_cert_from_volume(self):
         self.set_compute_api_version('2.63')
@@ -4316,7 +4307,7 @@ class TestServerCreate(TestServer):
             'directly from images',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_trusted_image_cert_from_snapshot(self):
         self.set_compute_api_version('2.63')
@@ -4349,7 +4340,7 @@ class TestServerCreate(TestServer):
             'directly from images',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
     def test_server_create_with_trusted_image_cert_boot_from_volume(self):
         self.set_compute_api_version('2.63')
@@ -4385,16 +4376,16 @@ class TestServerCreate(TestServer):
             'directly from images',
             str(exc),
         )
-        self.compute_sdk_client.create_server.assert_not_called()
+        self.compute_client.create_server.assert_not_called()
 
 
 class TestServerDelete(compute_fakes.TestComputev2):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.delete_server.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.delete_server.return_value = None
 
         # Get the command object to test
         self.cmd = server.DeleteServer(self.app, None)
@@ -4410,10 +4401,10 @@ class TestServerDelete(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False, all_projects=False
         )
-        self.compute_sdk_client.delete_server.assert_called_once_with(
+        self.compute_client.delete_server.assert_called_once_with(
             self.server, force=False
         )
         self.assertIsNone(result)
@@ -4430,18 +4421,18 @@ class TestServerDelete(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False, all_projects=False
         )
-        self.compute_sdk_client.delete_server.assert_called_once_with(
+        self.compute_client.delete_server.assert_called_once_with(
             self.server, force=True
         )
         self.assertIsNone(result)
 
     def test_server_delete_multi_servers(self):
-        servers = compute_fakes.create_sdk_servers(count=3)
-        self.compute_sdk_client.find_server.return_value = None
-        self.compute_sdk_client.find_server.side_effect = servers
+        servers = compute_fakes.create_servers(count=3)
+        self.compute_client.find_server.return_value = None
+        self.compute_client.find_server.side_effect = servers
 
         arglist = []
         verifylist = []
@@ -4454,13 +4445,13 @@ class TestServerDelete(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_has_calls(
+        self.compute_client.find_server.assert_has_calls(
             [
                 mock.call(s.id, ignore_missing=False, all_projects=False)
                 for s in servers
             ]
         )
-        self.compute_sdk_client.delete_server.assert_has_calls(
+        self.compute_client.delete_server.assert_has_calls(
             [mock.call(s, force=False) for s in servers]
         )
         self.assertIsNone(result)
@@ -4478,10 +4469,10 @@ class TestServerDelete(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False, all_projects=True
         )
-        self.compute_sdk_client.delete_server.assert_called_once_with(
+        self.compute_client.delete_server.assert_called_once_with(
             self.server, force=False
         )
         self.assertIsNone(result)
@@ -4499,20 +4490,20 @@ class TestServerDelete(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False, all_projects=False
         )
-        self.compute_sdk_client.delete_server.assert_called_once_with(
+        self.compute_client.delete_server.assert_called_once_with(
             self.server, force=False
         )
-        self.compute_sdk_client.wait_for_delete.assert_called_once_with(
+        self.compute_client.wait_for_delete.assert_called_once_with(
             self.server,
             callback=mock.ANY,
         )
         self.assertIsNone(result)
 
     def test_server_delete_wait_fails(self):
-        self.compute_sdk_client.wait_for_delete.side_effect = (
+        self.compute_client.wait_for_delete.side_effect = (
             sdk_exceptions.ResourceTimeout()
         )
 
@@ -4530,13 +4521,13 @@ class TestServerDelete(compute_fakes.Tes
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False, all_projects=False
         )
-        self.compute_sdk_client.delete_server.assert_called_once_with(
+        self.compute_client.delete_server.assert_called_once_with(
             self.server, force=False
         )
-        self.compute_sdk_client.wait_for_delete.assert_called_once_with(
+        self.compute_client.wait_for_delete.assert_called_once_with(
             self.server,
             callback=mock.ANY,
         )
@@ -4567,9 +4558,7 @@ class TestServerDumpCreate(TestServer):
 
         self.assertIsNone(result)
         for s in servers:
-            s.trigger_crash_dump.assert_called_once_with(
-                self.compute_sdk_client
-            )
+            s.trigger_crash_dump.assert_called_once_with(self.compute_client)
 
     def test_server_dump_one_server(self):
         self.run_test_server_dump(1)
@@ -4603,6 +4592,16 @@ class _TestServerList(TestServer):
         'Pinned Availability Zone',
         'Host',
         'Properties',
+        'Scheduler Hints',
+    )
+    columns_all_projects = (
+        'ID',
+        'Name',
+        'Status',
+        'Networks',
+        'Image',
+        'Flavor',
+        'Project ID',
     )
 
     def setUp(self):
@@ -4645,12 +4644,12 @@ class _TestServerList(TestServer):
         self.image_client.get_image.return_value = self.image
 
         self.flavor = compute_fakes.create_one_flavor()
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
+        self.compute_client.find_flavor.return_value = self.flavor
         self.attrs['flavor'] = {'original_name': self.flavor.name}
 
         # The servers to be listed.
         self.servers = self.setup_sdk_servers_mock(3)
-        self.compute_sdk_client.servers.return_value = self.servers
+        self.compute_client.servers.return_value = self.servers
 
         # Get the command object to test
         self.cmd = server.ListServer(self.app, None)
@@ -4669,7 +4668,7 @@ class TestServerList(_TestServerList):
         ]
 
         Flavor = collections.namedtuple('Flavor', 'id name')
-        self.compute_sdk_client.flavors.return_value = [
+        self.compute_client.flavors.return_value = [
             Flavor(id=s.flavor['id'], name=self.flavor.name)
             for s in self.servers
         ]
@@ -4699,9 +4698,9 @@ class TestServerList(_TestServerList):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_called()
-        self.compute_sdk_client.flavors.assert_called()
+        self.compute_client.flavors.assert_called()
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
 
@@ -4713,14 +4712,14 @@ class TestServerList(_TestServerList):
             ('deleted', False),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        self.compute_sdk_client.servers.return_value = []
+        self.compute_client.servers.return_value = []
         self.data = ()
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_not_called()
-        self.compute_sdk_client.flavors.assert_not_called()
+        self.compute_client.flavors.assert_not_called()
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
 
@@ -4742,6 +4741,7 @@ class TestServerList(_TestServerList):
                 getattr(s, 'pinned_availability_zone', ''),
                 server.HostColumn(getattr(s, 'hypervisor_hostname')),
                 format_columns.DictColumn(s.metadata),
+                format_columns.DictListColumn(None),
             )
             for s in self.servers
         )
@@ -4755,15 +4755,45 @@ class TestServerList(_TestServerList):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         image_ids = {s.image['id'] for s in self.servers if s.image}
         self.image_client.images.assert_called_once_with(
             id=f'in:{",".join(image_ids)}',
         )
-        self.compute_sdk_client.flavors.assert_called_once_with(is_public=None)
+        self.compute_client.flavors.assert_called_once_with(is_public=None)
         self.assertEqual(self.columns_long, columns)
         self.assertEqual(self.data, tuple(data))
 
+    def test_server_list_all_projects_option(self):
+        self.data = tuple(
+            (
+                s.id,
+                s.name,
+                s.status,
+                server.AddressesColumn(s.addresses),
+                # Image will be an empty string if boot-from-volume
+                self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
+                self.flavor.name,
+                s.project_id,
+            )
+            for s in self.servers
+        )
+        arglist = [
+            '--all-projects',
+        ]
+        verifylist = [
+            ('all_projects', True),
+            ('long', False),
+            ('deleted', False),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.image_client.images.assert_called()
+        self.compute_client.flavors.assert_called()
+        self.assertEqual(self.columns_all_projects, columns)
+        self.assertEqual(self.data, tuple(data))
+
     def test_server_list_column_option(self):
         arglist = [
             '-c',
@@ -4790,6 +4820,8 @@ class TestServerList(_TestServerList):
             'Host',
             '-c',
             'Properties',
+            '-c',
+            'Scheduler Hints',
             '--long',
         ]
         verifylist = [
@@ -4799,7 +4831,7 @@ class TestServerList(_TestServerList):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertIn('Project ID', columns)
         self.assertIn('User ID', columns)
         self.assertIn('Created At', columns)
@@ -4812,6 +4844,7 @@ class TestServerList(_TestServerList):
         self.assertIn('Pinned Availability Zone', columns)
         self.assertIn('Host', columns)
         self.assertIn('Properties', columns)
+        self.assertIn('Scheduler Hints', columns)
         self.assertCountEqual(columns, set(columns))
 
     def test_server_list_no_name_lookup_option(self):
@@ -4839,9 +4872,9 @@ class TestServerList(_TestServerList):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_not_called()
-        self.compute_sdk_client.flavors.assert_not_called()
+        self.compute_client.flavors.assert_not_called()
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
 
@@ -4870,9 +4903,9 @@ class TestServerList(_TestServerList):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_not_called()
-        self.compute_sdk_client.flavors.assert_not_called()
+        self.compute_client.flavors.assert_not_called()
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
 
@@ -4887,11 +4920,11 @@ class TestServerList(_TestServerList):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_not_called()
-        self.compute_sdk_client.flavors.assert_not_called()
+        self.compute_client.flavors.assert_not_called()
         self.image_client.get_image.assert_called()
-        self.compute_sdk_client.find_flavor.assert_called()
+        self.compute_client.find_flavor.assert_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -4908,9 +4941,9 @@ class TestServerList(_TestServerList):
         )
 
         self.kwargs['image'] = self.image.id
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_not_called()
-        self.compute_sdk_client.flavors.assert_called_once()
+        self.compute_client.flavors.assert_called_once()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -4922,14 +4955,14 @@ class TestServerList(_TestServerList):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_flavor.assert_has_calls(
+        self.compute_client.find_flavor.assert_has_calls(
             [mock.call(self.flavor.id, ignore_missing=False)]
         )
 
         self.kwargs['flavor'] = self.flavor.id
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.image_client.images.assert_called_once()
-        self.compute_sdk_client.flavors.assert_not_called()
+        self.compute_client.flavors.assert_not_called()
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -4946,7 +4979,7 @@ class TestServerList(_TestServerList):
 
         self.kwargs['changes-since'] = '2016-03-04T06:27:59Z'
         self.kwargs['deleted'] = True
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -4967,7 +5000,7 @@ class TestServerList(_TestServerList):
             self.fail('CommandError should be raised.')
         except exceptions.CommandError as e:
             self.assertEqual(
-                'Invalid changes-since value: Invalid time ' 'value', str(e)
+                'Invalid changes-since value: Invalid time value', str(e)
             )
         mock_parse_isotime.assert_called_once_with('Invalid time value')
 
@@ -4989,7 +5022,7 @@ class TestServerList(_TestServerList):
 
         self.kwargs['tags'] = 'tag1,tag2'
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -5032,7 +5065,7 @@ class TestServerList(_TestServerList):
 
         self.kwargs['not-tags'] = 'tag1,tag2'
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, tuple(data))
@@ -5071,7 +5104,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['availability_zone'] = 'test-az'
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5088,7 +5121,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['key_name'] = 'test-key'
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5104,7 +5137,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['config_drive'] = True
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5120,7 +5153,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['config_drive'] = False
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5137,7 +5170,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['progress'] = '100'
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5168,7 +5201,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['vm_state'] = 'active'
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5185,7 +5218,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['task_state'] = 'deleting'
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5202,7 +5235,7 @@ class TestServerList(_TestServerList):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['power_state'] = 1
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
@@ -5225,6 +5258,7 @@ class TestServerList(_TestServerList):
                 getattr(s, 'pinned_availability_zone', ''),
                 server.HostColumn(getattr(s, 'hypervisor_hostname')),
                 format_columns.DictColumn(s.metadata),
+                format_columns.DictListColumn(s.scheduler_hints),
             )
             for s in self.servers
         )
@@ -5239,18 +5273,18 @@ class TestServerList(_TestServerList):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertEqual(self.columns_long, columns)
         self.assertEqual(tuple(self.data1), tuple(data))
 
         # Next test with host_status in the data -- the column should be
         # present in this case.
-        self.compute_sdk_client.servers.reset_mock()
+        self.compute_client.servers.reset_mock()
 
         self.attrs['host_status'] = 'UP'
         servers = self.setup_sdk_servers_mock(3)
-        self.compute_sdk_client.servers.return_value = servers
+        self.compute_client.servers.return_value = servers
 
         # Make sure the returned image and flavor IDs match the servers.
         Image = collections.namedtuple('Image', 'id name')
@@ -5280,6 +5314,7 @@ class TestServerList(_TestServerList):
                 getattr(s, 'pinned_availability_zone', ''),
                 server.HostColumn(getattr(s, 'hypervisor_hostname')),
                 format_columns.DictColumn(s.metadata),
+                format_columns.DictListColumn(s.scheduler_hints),
                 s.host_status,
             )
             for s in servers
@@ -5287,7 +5322,7 @@ class TestServerList(_TestServerList):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertEqual(columns_long, columns)
         self.assertEqual(tuple(self.data2), tuple(data))
@@ -5317,6 +5352,7 @@ class TestServerListV273(_TestServerList
         'Pinned Availability Zone',
         'Host',
         'Properties',
+        'Scheduler Hints',
     )
 
     def setUp(self):
@@ -5336,7 +5372,7 @@ class TestServerListV273(_TestServerList
 
         # The servers to be listed.
         self.servers = self.setup_sdk_servers_mock(3)
-        self.compute_sdk_client.servers.return_value = self.servers
+        self.compute_client.servers.return_value = self.servers
 
         Image = collections.namedtuple('Image', 'id name')
         self.image_client.images.return_value = [
@@ -5348,7 +5384,7 @@ class TestServerListV273(_TestServerList
 
         # The flavor information is embedded, so now reason for this to be
         # called
-        self.compute_sdk_client.flavors = mock.NonCallableMock()
+        self.compute_client.flavors = mock.NonCallableMock()
 
         self.data = tuple(
             (
@@ -5384,7 +5420,7 @@ class TestServerListV273(_TestServerList
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['locked'] = True
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertCountEqual(self.columns, columns)
         self.assertCountEqual(self.data, tuple(data))
@@ -5399,7 +5435,7 @@ class TestServerListV273(_TestServerList
         columns, data = self.cmd.take_action(parsed_args)
 
         self.kwargs['locked'] = False
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertCountEqual(self.columns, columns)
         self.assertCountEqual(self.data, tuple(data))
@@ -5432,7 +5468,7 @@ class TestServerListV273(_TestServerList
         self.kwargs['changes-before'] = '2016-03-05T06:27:59Z'
         self.kwargs['deleted'] = True
 
-        self.compute_sdk_client.servers.assert_called_with(**self.kwargs)
+        self.compute_client.servers.assert_called_with(**self.kwargs)
 
         self.assertCountEqual(self.columns, columns)
         self.assertCountEqual(self.data, tuple(data))
@@ -5454,7 +5490,7 @@ class TestServerListV273(_TestServerList
             self.fail('CommandError should be raised.')
         except exceptions.CommandError as e:
             self.assertEqual(
-                'Invalid changes-before value: Invalid time ' 'value', str(e)
+                'Invalid changes-before value: Invalid time value', str(e)
             )
         mock_parse_isotime.assert_called_once_with('Invalid time value')
 
@@ -5491,9 +5527,7 @@ class TestServerListV273(_TestServerList
             ],
             "networks": {},
         }
-        fake_server = compute_fakes.fakes.FakeResource(
-            info=server_dict,
-        )
+        fake_server = _server.Server(**server_dict)
         self.servers.append(fake_server)
         columns, data = self.cmd.take_action(parsed_args)
         # get the first three servers out since our interest is in the partial
@@ -5504,9 +5538,9 @@ class TestServerListV273(_TestServerList
         partial_server = next(data)
         expected_row = (
             'server-id-95a56bfc4xxxxxx28d7e418bfd97813a',
-            '',
+            None,
             'UNKNOWN',
-            server.AddressesColumn(''),
+            server.AddressesColumn(None),
             '',
             '',
         )
@@ -5515,8 +5549,8 @@ class TestServerListV273(_TestServerList
 
 class TestServerAction(compute_fakes.TestComputev2):
     def run_method_with_sdk_servers(self, method_name, server_count):
-        servers = compute_fakes.create_sdk_servers(count=server_count)
-        self.compute_sdk_client.find_server.side_effect = servers
+        servers = compute_fakes.create_servers(count=server_count)
+        self.compute_client.find_server.side_effect = servers
 
         arglist = [s.id for s in servers]
         verifylist = [
@@ -5527,7 +5561,7 @@ class TestServerAction(compute_fakes.Tes
         result = self.cmd.take_action(parsed_args)
 
         calls = [mock.call(s.id) for s in servers]
-        method = getattr(self.compute_sdk_client, method_name)
+        method = getattr(self.compute_client, method_name)
         method.assert_has_calls(calls)
         self.assertIsNone(result)
 
@@ -5548,9 +5582,9 @@ class TestServerLock(TestServerAction):
     def test_server_lock_with_reason(self):
         self.set_compute_api_version('2.73')
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.lock_server.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.lock_server.return_value = None
 
         arglist = [
             self.server.id,
@@ -5565,11 +5599,11 @@ class TestServerLock(TestServerAction):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id,
             ignore_missing=False,
         )
-        self.compute_sdk_client.lock_server.assert_called_with(
+        self.compute_client.lock_server.assert_called_with(
             self.server.id,
             locked_reason="blah",
         )
@@ -5577,11 +5611,11 @@ class TestServerLock(TestServerAction):
     def test_server_lock_with_reason_multi_servers(self):
         self.set_compute_api_version('2.73')
 
-        server_a = compute_fakes.create_one_sdk_server()
-        server_b = compute_fakes.create_one_sdk_server()
+        server_a = compute_fakes.create_one_server()
+        server_b = compute_fakes.create_one_server()
 
-        self.compute_sdk_client.find_server.side_effect = [server_a, server_b]
-        self.compute_sdk_client.lock_server.return_value = None
+        self.compute_client.find_server.side_effect = [server_a, server_b]
+        self.compute_client.lock_server.return_value = None
         arglist = [
             server_a.id,
             server_b.id,
@@ -5596,8 +5630,8 @@ class TestServerLock(TestServerAction):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.assertEqual(2, self.compute_sdk_client.find_server.call_count)
-        self.compute_sdk_client.lock_server.assert_has_calls(
+        self.assertEqual(2, self.compute_client.find_server.call_count)
+        self.compute_client.lock_server.assert_has_calls(
             [
                 mock.call(server_a.id, locked_reason="choo..choo"),
                 mock.call(server_b.id, locked_reason="choo..choo"),
@@ -5607,7 +5641,7 @@ class TestServerLock(TestServerAction):
     def test_server_lock_with_reason_pre_v273(self):
         self.set_compute_api_version('2.72')
 
-        server = compute_fakes.create_one_sdk_server()
+        server = compute_fakes.create_one_server()
 
         arglist = [
             server.id,
@@ -5635,10 +5669,10 @@ class TestServerMigrate(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.migrate_server.return_value = None
-        self.compute_sdk_client.live_migrate_server.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.migrate_server.return_value = None
+        self.compute_client.live_migrate_server.return_value = None
 
         # Get the command object to test
         self.cmd = server.MigrateServer(self.app, None)
@@ -5657,13 +5691,13 @@ class TestServerMigrate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_called_once_with(
+        self.compute_client.migrate_server.assert_called_once_with(
             self.server,
         )
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_migrate_with_host(self):
@@ -5687,13 +5721,13 @@ class TestServerMigrate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_called_once_with(
+        self.compute_client.migrate_server.assert_called_once_with(
             self.server, host='fakehost'
         )
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_migrate_with_block_migration(self):
@@ -5713,11 +5747,11 @@ class TestServerMigrate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
 
     def test_server_migrate_with_disk_overcommit(self):
         arglist = [
@@ -5736,11 +5770,11 @@ class TestServerMigrate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
 
     def test_server_migrate_with_host_pre_v256(self):
         # Tests that --host is not allowed for a cold migration
@@ -5772,11 +5806,11 @@ class TestServerMigrate(TestServer):
             str(ex),
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
 
     def test_server_live_migrate(self):
         # Tests the --live-migration option without --host or --live.
@@ -5795,16 +5829,16 @@ class TestServerMigrate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.live_migrate_server.assert_called_once_with(
+        self.compute_client.live_migrate_server.assert_called_once_with(
             self.server,
             block_migration=False,
             host=None,
             disk_overcommit=False,
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_live_migrate_with_host(self):
@@ -5828,17 +5862,17 @@ class TestServerMigrate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         # No disk_overcommit and block_migration defaults to auto with
         # microversion >= 2.25
-        self.compute_sdk_client.live_migrate_server.assert_called_once_with(
+        self.compute_client.live_migrate_server.assert_called_once_with(
             self.server,
             block_migration='auto',
             host='fakehost',
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_live_migrate_with_host_pre_v230(self):
@@ -5871,11 +5905,11 @@ class TestServerMigrate(TestServer):
             str(ex),
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
 
     def test_server_block_live_migrate(self):
         self.set_compute_api_version('2.24')
@@ -5895,18 +5929,18 @@ class TestServerMigrate(TestServer):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         # No disk_overcommit and block_migration defaults to auto with
         # microversion >= 2.25
-        self.compute_sdk_client.live_migrate_server.assert_called_once_with(
+        self.compute_client.live_migrate_server.assert_called_once_with(
             self.server,
             block_migration=True,
             disk_overcommit=False,
             host=None,
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_live_migrate_with_disk_overcommit(self):
@@ -5927,16 +5961,16 @@ class TestServerMigrate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.live_migrate_server.assert_called_once_with(
+        self.compute_client.live_migrate_server.assert_called_once_with(
             self.server,
             block_migration=False,
             disk_overcommit=True,
             host=None,
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_live_migrate_with_disk_overcommit_post_v224(self):
@@ -5958,16 +5992,16 @@ class TestServerMigrate(TestServer):
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         # There should be no 'disk_over_commit' value present
-        self.compute_sdk_client.live_migrate_server.assert_called_once_with(
+        self.compute_client.live_migrate_server.assert_called_once_with(
             self.server,
             block_migration='auto',
             host=None,
         )
-        self.compute_sdk_client.migrate_server.assert_not_called()
+        self.compute_client.migrate_server.assert_not_called()
         self.assertIsNone(result)
 
         # A warning should have been logged for using --disk-overcommit.
@@ -5993,15 +6027,15 @@ class TestServerMigrate(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_called_once_with(
+        self.compute_client.migrate_server.assert_called_once_with(
             self.server,
         )
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             success_status=('active', 'verify_resize'),
             callback=mock.ANY,
@@ -6026,15 +6060,15 @@ class TestServerMigrate(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.migrate_server.assert_called_once_with(
+        self.compute_client.migrate_server.assert_called_once_with(
             self.server,
         )
-        self.compute_sdk_client.live_migrate_server.assert_not_called()
+        self.compute_client.live_migrate_server.assert_not_called()
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             success_status=('active', 'verify_resize'),
             callback=mock.ANY,
@@ -6045,7 +6079,7 @@ class TestServerReboot(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.reboot_server.return_value = None
+        self.compute_client.reboot_server.return_value = None
 
         self.cmd = server.RebootServer(self.app, None)
 
@@ -6064,7 +6098,7 @@ class TestServerReboot(TestServer):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.reboot_server.assert_called_once_with(
+        self.compute_client.reboot_server.assert_called_once_with(
             servers[0].id,
             'SOFT',
         )
@@ -6086,7 +6120,7 @@ class TestServerReboot(TestServer):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.reboot_server.assert_called_once_with(
+        self.compute_client.reboot_server.assert_called_once_with(
             servers[0].id,
             'HARD',
         )
@@ -6110,12 +6144,12 @@ class TestServerReboot(TestServer):
         result = self.cmd.take_action(parsed_args)
 
         self.assertIsNone(result)
-        self.compute_sdk_client.reboot_server.assert_called_once_with(
+        self.compute_client.reboot_server.assert_called_once_with(
             servers[0].id,
             'SOFT',
         )
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             servers[0].id,
             callback=mock.ANY,
         )
@@ -6144,12 +6178,12 @@ class TestServerReboot(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.reboot_server.assert_called_once_with(
+        self.compute_client.reboot_server.assert_called_once_with(
             servers[0].id,
             'SOFT',
         )
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             servers[0].id,
             callback=mock.ANY,
         )
@@ -6180,9 +6214,9 @@ class TestServerRebuild(TestServer):
             'status': 'ACTIVE',
             'image': {'id': self.image.id},
         }
-        self.server = compute_fakes.create_one_sdk_server(attrs=attrs)
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.rebuild_server.return_value = self.server
+        self.server = compute_fakes.create_one_server(attrs=attrs)
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.rebuild_server.return_value = self.server
 
         self.cmd = server.RebuildServer(self.app, None)
 
@@ -6204,14 +6238,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_called_with(
             image_name, ignore_missing=False
         )
         self.image_client.get_image.assert_called_with(self.image.id)
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, image
         )
 
@@ -6225,14 +6259,14 @@ class TestServerRebuild(TestServer):
         # Get the command object to test.
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image
         )
 
@@ -6269,14 +6303,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, name=name
         )
 
@@ -6293,14 +6327,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, preserve_ephemeral=True
         )
 
@@ -6318,14 +6352,14 @@ class TestServerRebuild(TestServer):
         # Get the command object to test
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, preserve_ephemeral=False
         )
 
@@ -6337,14 +6371,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server,
             self.image,
             admin_password=password,
@@ -6360,14 +6394,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, description=description
         )
 
@@ -6397,19 +6431,19 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=['active'],
@@ -6431,17 +6465,17 @@ class TestServerRebuild(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_called_once_with(self.image.id)
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=['active'],
@@ -6462,19 +6496,19 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=['shutoff'],
@@ -6495,19 +6529,19 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=['active'],
@@ -6527,12 +6561,12 @@ class TestServerRebuild(TestServer):
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_called_once_with(self.image.id)
-        self.compute_sdk_client.rebuild_server.assert_not_called()
+        self.compute_client.rebuild_server.assert_not_called()
 
     def test_rebuild_with_property(self):
         arglist = [
@@ -6551,14 +6585,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, metadata=expected_properties
         )
 
@@ -6579,14 +6613,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, key_name=self.server.key_name
         )
 
@@ -6624,14 +6658,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, key_name=None
         )
 
@@ -6679,14 +6713,14 @@ class TestServerRebuild(TestServer):
         # Ensure the userdata file is opened
         mock_file.assert_called_with('userdata.sh', 'rb')
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server,
             self.image,
             user_data=base64.b64encode(user_data).decode('utf-8'),
@@ -6726,14 +6760,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, user_data=None
         )
 
@@ -6787,14 +6821,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, trusted_image_certificates=['foo', 'bar']
         )
 
@@ -6833,14 +6867,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, trusted_image_certificates=None
         )
 
@@ -6877,14 +6911,14 @@ class TestServerRebuild(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_not_called()
         self.image_client.get_image.assert_has_calls(
             [mock.call(self.image.id), mock.call(self.image.id)]
         )
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.image, hostname='new-hostname'
         )
 
@@ -6915,9 +6949,9 @@ class TestServerRebuildVolumeBacked(Test
             'status': 'ACTIVE',
             'image': '',
         }
-        self.server = compute_fakes.create_one_sdk_server(attrs=attrs)
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.rebuild_server.return_value = self.server
+        self.server = compute_fakes.create_one_server(attrs=attrs)
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.rebuild_server.return_value = self.server
 
         self.cmd = server.RebuildServer(self.app, None)
 
@@ -6939,14 +6973,14 @@ class TestServerRebuildVolumeBacked(Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.image_client.find_image.assert_called_with(
             self.new_image.id, ignore_missing=False
         )
         self.image_client.get_image.assert_not_called()
-        self.compute_sdk_client.rebuild_server.assert_called_once_with(
+        self.compute_client.rebuild_server.assert_called_once_with(
             self.server, self.new_image
         )
 
@@ -7005,14 +7039,15 @@ class TestServerEvacuate(TestServer):
             'image': self.image,
             'networks': {},
             'adminPass': 'passw0rd',
+            'status': 'ACTIVE',
         }
-        self.server = compute_fakes.create_one_sdk_server(attrs=attrs)
+        self.server = compute_fakes.create_one_server(attrs=attrs)
         attrs['id'] = self.server.id
-        self.new_server = compute_fakes.create_one_sdk_server(attrs=attrs)
+        self.new_server = compute_fakes.create_one_server(attrs=attrs)
 
         # Return value for utils.find_resource for server.
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.get_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.get_server.return_value = self.server
 
         self.cmd = server.EvacuateServer(self.app, None)
 
@@ -7020,15 +7055,13 @@ class TestServerEvacuate(TestServer):
         parsed_args = self.check_parser(self.cmd, args, verify_args)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.evacuate_server.assert_called_once_with(
+        self.compute_client.evacuate_server.assert_called_once_with(
             self.server, **evac_args
         )
-        self.compute_sdk_client.get_server.assert_called_once_with(
-            self.server.id
-        )
+        self.compute_client.get_server.assert_called_once_with(self.server.id)
 
     def test_evacuate(self):
         args = [
@@ -7142,8 +7175,35 @@ class TestServerEvacuate(TestServer):
         }
         self._test_evacuate(args, verify_args, evac_args)
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
+            success_status=['ACTIVE'],
+            callback=mock.ANY,
+        )
+
+    @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
+    def test_evacuate_with_wait_ok_shutoff(self, mock_wait_for_status):
+        self.server.status = 'SHUTOFF'
+        self.compute_client.get_server.return_value = self.server
+
+        args = [
+            self.server.id,
+            '--wait',
+        ]
+        verify_args = [
+            ('server', self.server.id),
+            ('wait', True),
+        ]
+        evac_args = {
+            'host': None,
+            'on_shared_storage': False,
+            'admin_pass': None,
+        }
+        self._test_evacuate(args, verify_args, evac_args)
+        mock_wait_for_status.assert_called_once_with(
+            self.compute_client.get_server,
+            self.server.id,
+            success_status=['ACTIVE', 'SHUTOFF'],
             callback=mock.ANY,
         )
 
@@ -7152,7 +7212,7 @@ class TestServerRemoveFixedIP(compute_fa
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
+        self.server = compute_fakes.create_one_server()
 
         # Get the command object to test
         self.cmd = server.RemoveFixedIP(self.app, None)
@@ -7170,12 +7230,10 @@ class TestServerRemoveFixedIP(compute_fa
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.remove_fixed_ip_from_server(
-            self.server, '1.2.3.4'
-        )
+        self.compute_client.remove_fixed_ip_from_server(self.server, '1.2.3.4')
         self.assertIsNone(result)
 
 
@@ -7183,8 +7241,8 @@ class TestServerRescue(compute_fakes.Tes
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.cmd = server.RescueServer(self.app, None)
 
@@ -7199,10 +7257,10 @@ class TestServerRescue(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.rescue_server.assert_called_once_with(
+        self.compute_client.rescue_server.assert_called_once_with(
             self.server, admin_pass=None, image_ref=None
         )
         self.assertIsNone(result)
@@ -7226,10 +7284,10 @@ class TestServerRescue(compute_fakes.Tes
         self.image_client.find_image.assert_called_with(
             new_image.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.rescue_server.assert_called_once_with(
+        self.compute_client.rescue_server.assert_called_once_with(
             self.server, admin_pass=None, image_ref=new_image.id
         )
         self.assertIsNone(result)
@@ -7249,10 +7307,10 @@ class TestServerRescue(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.rescue_server.assert_called_once_with(
+        self.compute_client.rescue_server.assert_called_once_with(
             self.server, admin_pass=password, image_ref=None
         )
         self.assertIsNone(result)
@@ -7263,8 +7321,8 @@ class TestServerRemoveFloatingIPCompute(
         super().setUp()
 
         self.app.client_manager.network_endpoint_enabled = False
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.cmd = server.RemoveFloatingIP(self.app, None)
 
@@ -7281,10 +7339,10 @@ class TestServerRemoveFloatingIPCompute(
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False
         )
-        self.compute_sdk_client.remove_floating_ip_from_server.assert_called_once_with(
+        self.compute_client.remove_floating_ip_from_server.assert_called_once_with(
             self.server, '1.2.3.4'
         )
 
@@ -7352,7 +7410,7 @@ class TestServerRemovePort(TestServer):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.delete_server_interface.assert_called_with(
+        self.compute_client.delete_server_interface.assert_called_with(
             port_id, server=servers[0], ignore_missing=False
         )
         self.assertIsNone(result)
@@ -7381,9 +7439,7 @@ class TestServerRemoveNetwork(TestServer
 
         self.find_network = mock.Mock()
         self.app.client_manager.network.find_network = self.find_network
-        self.compute_sdk_client.server_interfaces.return_value = [
-            self.fake_inf
-        ]
+        self.compute_client.server_interfaces.return_value = [self.fake_inf]
 
     def _test_server_remove_network(self, network_id):
         self.fake_inf.net_id = network_id
@@ -7403,10 +7459,10 @@ class TestServerRemoveNetwork(TestServer
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.server_interfaces.assert_called_once_with(
+        self.compute_client.server_interfaces.assert_called_once_with(
             servers[0]
         )
-        self.compute_sdk_client.delete_server_interface.assert_called_once_with(
+        self.compute_client.delete_server_interface.assert_called_once_with(
             'fake-port', server=servers[0]
         )
         self.assertIsNone(result)
@@ -7427,9 +7483,11 @@ class TestServerRemoveSecurityGroup(Test
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.remove_security_group_from_server.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.remove_security_group_from_server.return_value = (
+            None
+        )
 
         # Get the command object to test
         self.cmd = server.RemoveServerSecurityGroup(self.app, None)
@@ -7454,14 +7512,14 @@ class TestServerRemoveSecurityGroup(Test
             ) as mock_find_nova_net_sg:
                 result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.remove_security_group_from_server.assert_called_once_with(
+        self.compute_client.remove_security_group_from_server.assert_called_once_with(
             self.server, {'name': 'fake_sg'}
         )
         mock_find_nova_net_sg.assert_called_once_with(
-            self.compute_sdk_client, 'fake_sg'
+            self.compute_client, 'fake_sg'
         )
         self.assertIsNone(result)
 
@@ -7475,10 +7533,10 @@ class TestServerRemoveSecurityGroup(Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.remove_security_group_from_server.assert_called_once_with(
+        self.compute_client.remove_security_group_from_server.assert_called_once_with(
             self.server, {'name': 'fake_sg'}
         )
         self.assertIsNone(result)
@@ -7488,13 +7546,13 @@ class TestServerResize(compute_fakes.Tes
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
         self.flavor = compute_fakes.create_one_flavor()
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
-        self.compute_sdk_client.resize_server.return_value = None
-        self.compute_sdk_client.revert_server_resize.return_value = None
-        self.compute_sdk_client.confirm_server_resize.return_value = None
+        self.compute_client.find_flavor.return_value = self.flavor
+        self.compute_client.resize_server.return_value = None
+        self.compute_client.revert_server_resize.return_value = None
+        self.compute_client.confirm_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.ResizeServer(self.app, None)
@@ -7512,11 +7570,11 @@ class TestServerResize(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_flavor.assert_not_called()
-        self.compute_sdk_client.resize_server.assert_not_called()
+        self.compute_client.find_flavor.assert_not_called()
+        self.compute_client.resize_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_resize(self):
@@ -7535,17 +7593,17 @@ class TestServerResize(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_flavor.assert_called_once_with(
+        self.compute_client.find_flavor.assert_called_once_with(
             self.flavor.id, ignore_missing=False
         )
-        self.compute_sdk_client.resize_server.assert_called_once_with(
+        self.compute_client.resize_server.assert_called_once_with(
             self.server, self.flavor
         )
-        self.compute_sdk_client.confirm_server_resize.assert_not_called()
-        self.compute_sdk_client.revert_server_resize.assert_not_called()
+        self.compute_client.confirm_server_resize.assert_not_called()
+        self.compute_client.revert_server_resize.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_resize_confirm(self):
@@ -7563,15 +7621,15 @@ class TestServerResize(compute_fakes.Tes
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_flavor.assert_not_called()
-        self.compute_sdk_client.resize_server.assert_not_called()
-        self.compute_sdk_client.confirm_server_resize.assert_called_once_with(
+        self.compute_client.find_flavor.assert_not_called()
+        self.compute_client.resize_server.assert_not_called()
+        self.compute_client.confirm_server_resize.assert_called_once_with(
             self.server
         )
-        self.compute_sdk_client.revert_server_resize.assert_not_called()
+        self.compute_client.revert_server_resize.assert_not_called()
         self.assertIsNone(result)
 
         # A warning should have been logged for using --confirm.
@@ -7596,13 +7654,13 @@ class TestServerResize(compute_fakes.Tes
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_flavor.assert_not_called()
-        self.compute_sdk_client.resize_server.assert_not_called()
-        self.compute_sdk_client.confirm_server_resize.assert_not_called()
-        self.compute_sdk_client.revert_server_resize.assert_called_once_with(
+        self.compute_client.find_flavor.assert_not_called()
+        self.compute_client.resize_server.assert_not_called()
+        self.compute_client.confirm_server_resize.assert_not_called()
+        self.compute_client.revert_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7632,20 +7690,20 @@ class TestServerResize(compute_fakes.Tes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_flavor.assert_called_once_with(
+        self.compute_client.find_flavor.assert_called_once_with(
             self.flavor.id, ignore_missing=False
         )
-        self.compute_sdk_client.resize_server.assert_called_once_with(
+        self.compute_client.resize_server.assert_called_once_with(
             self.server, self.flavor
         )
-        self.compute_sdk_client.confirm_server_resize.assert_not_called()
-        self.compute_sdk_client.revert_server_resize.assert_not_called()
+        self.compute_client.confirm_server_resize.assert_not_called()
+        self.compute_client.revert_server_resize.assert_not_called()
 
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             success_status=('active', 'verify_resize'),
             callback=mock.ANY,
@@ -7672,20 +7730,20 @@ class TestServerResize(compute_fakes.Tes
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_flavor.assert_called_once_with(
+        self.compute_client.find_flavor.assert_called_once_with(
             self.flavor.id, ignore_missing=False
         )
-        self.compute_sdk_client.resize_server.assert_called_once_with(
+        self.compute_client.resize_server.assert_called_once_with(
             self.server, self.flavor
         )
-        self.compute_sdk_client.confirm_server_resize.assert_not_called()
-        self.compute_sdk_client.revert_server_resize.assert_not_called()
+        self.compute_client.confirm_server_resize.assert_not_called()
+        self.compute_client.revert_server_resize.assert_not_called()
 
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             success_status=('active', 'verify_resize'),
             callback=mock.ANY,
@@ -7696,9 +7754,9 @@ class TestServerResizeConfirm(compute_fa
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.confirm_server_resize.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.confirm_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.ResizeConfirm(self.app, None)
@@ -7714,10 +7772,10 @@ class TestServerResizeConfirm(compute_fa
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.confirm_server_resize.assert_called_once_with(
+        self.compute_client.confirm_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7728,9 +7786,9 @@ class TestServerMigrateConfirm(compute_f
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.confirm_server_resize.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.confirm_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.MigrateConfirm(self.app, None)
@@ -7747,10 +7805,10 @@ class TestServerMigrateConfirm(compute_f
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.confirm_server_resize.assert_called_once_with(
+        self.compute_client.confirm_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7766,9 +7824,9 @@ class TestServerConfirmMigration(compute
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.confirm_server_resize.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.confirm_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.ConfirmMigration(self.app, None)
@@ -7784,10 +7842,10 @@ class TestServerConfirmMigration(compute
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.confirm_server_resize.assert_called_once_with(
+        self.compute_client.confirm_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7797,9 +7855,9 @@ class TestServerResizeRevert(compute_fak
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.revert_server_resize.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.revert_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.ResizeRevert(self.app, None)
@@ -7815,10 +7873,10 @@ class TestServerResizeRevert(compute_fak
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_server_resize.assert_called_once_with(
+        self.compute_client.revert_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7829,9 +7887,9 @@ class TestServerMigrateRevert(compute_fa
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.revert_server_resize.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.revert_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.MigrateRevert(self.app, None)
@@ -7848,10 +7906,10 @@ class TestServerMigrateRevert(compute_fa
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_server_resize.assert_called_once_with(
+        self.compute_client.revert_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7867,9 +7925,9 @@ class TestServerRevertMigration(compute_
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.revert_server_resize.return_value = None
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.revert_server_resize.return_value = None
 
         # Get the command object to test
         self.cmd = server.RevertMigration(self.app, None)
@@ -7885,10 +7943,10 @@ class TestServerRevertMigration(compute_
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.revert_server_resize.assert_called_once_with(
+        self.compute_client.revert_server_resize.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -7926,8 +7984,8 @@ class TestServerSet(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         # Get the command object to test
         self.cmd = server.SetServer(self.app, None)
@@ -7939,18 +7997,19 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_state(self):
         arglist = [
             '--state',
             'active',
+            '--auto-approve',
             self.server.id,
         ]
         verifylist = [
@@ -7961,14 +8020,62 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.reset_server_state.assert_called_once_with(
+        self.compute_client.reset_server_state.assert_called_once_with(
             self.server, state='active'
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
+        self.assertIsNone(result)
+
+    def test_server_set_with_state_prompt_y(self):
+        arglist = [
+            '--state',
+            'active',
+            self.server.id,
+        ]
+        verifylist = [
+            ('state', 'active'),
+            ('server', self.server.id),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        with mock.patch('getpass.getpass', return_value='y'):
+            result = self.cmd.take_action(parsed_args)
+
+        self.compute_client.reset_server_state.assert_called_once_with(
+            self.server, state='active'
+        )
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
+        self.assertIsNone(result)
+
+    def test_server_set_with_state_prompt_n(self):
+        arglist = [
+            '--state',
+            'active',
+            self.server.id,
+        ]
+        verifylist = [
+            ('state', 'active'),
+            ('server', self.server.id),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        with mock.patch('getpass.getpass', return_value='n'):
+            result = self.cmd.take_action(parsed_args)
+
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_invalid_state(self):
@@ -8003,14 +8110,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.update_server.assert_called_once_with(
+        self.compute_client.update_server.assert_called_once_with(
             self.server, name='foo_name'
         )
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_property(self):
@@ -8029,14 +8136,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.set_server_metadata.assert_called_once_with(
+        self.compute_client.set_server_metadata.assert_called_once_with(
             self.server, key1='value1', key2='value2'
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_password(self):
@@ -8053,14 +8160,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.change_server_password.assert_called_once_with(
+        self.compute_client.change_server_password.assert_called_once_with(
             self.server, 'foo'
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_no_password(self):
@@ -8076,14 +8183,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.clear_server_password.assert_called_once_with(
+        self.compute_client.clear_server_password.assert_called_once_with(
             self.server
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     # TODO(stephenfin): Remove this in a future major version
@@ -8103,14 +8210,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.change_server_password.assert_called_once_with(
+        self.compute_client.change_server_password.assert_called_once_with(
             self.server, mock.sentinel.fake_pass
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_description(self):
@@ -8129,14 +8236,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.update_server.assert_called_once_with(
+        self.compute_client.update_server.assert_called_once_with(
             self.server, description='foo_description'
         )
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_description_pre_v219(self):
@@ -8175,17 +8282,17 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.add_tag_to_server.assert_has_calls(
+        self.compute_client.add_tag_to_server.assert_has_calls(
             [
                 mock.call(self.server, tag='tag1'),
                 mock.call(self.server, tag='tag2'),
             ]
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_tag_pre_v226(self):
@@ -8227,14 +8334,14 @@ class TestServerSet(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.update_server.assert_called_once_with(
+        self.compute_client.update_server.assert_called_once_with(
             self.server, hostname='foo-hostname'
         )
-        self.compute_sdk_client.set_server_metadata.assert_not_called()
-        self.compute_sdk_client.reset_server_state.assert_not_called()
-        self.compute_sdk_client.change_server_password.assert_not_called()
-        self.compute_sdk_client.clear_server_password.assert_not_called()
-        self.compute_sdk_client.add_tag_to_server.assert_not_called()
+        self.compute_client.set_server_metadata.assert_not_called()
+        self.compute_client.reset_server_state.assert_not_called()
+        self.compute_client.change_server_password.assert_not_called()
+        self.compute_client.clear_server_password.assert_not_called()
+        self.compute_client.add_tag_to_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_set_with_hostname_pre_v290(self):
@@ -8259,12 +8366,12 @@ class TestServerShelve(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server(
+        self.server = compute_fakes.create_one_server(
             attrs={'status': 'ACTIVE'},
         )
 
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.shelve_server.return_value = None
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.shelve_server.return_value = None
 
         # Get the command object to test
         self.cmd = server.ShelveServer(self.app, None)
@@ -8281,14 +8388,12 @@ class TestServerShelve(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.shelve_server.assert_called_with(
-            self.server.id
-        )
-        self.compute_sdk_client.shelve_offload_server.assert_not_called()
+        self.compute_client.shelve_server.assert_called_with(self.server.id)
+        self.compute_client.shelve_offload_server.assert_not_called()
 
     def test_shelve_already_shelved(self):
         self.server.status = 'SHELVED'
@@ -8304,12 +8409,12 @@ class TestServerShelve(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.shelve_server.assert_not_called()
-        self.compute_sdk_client.shelve_offload_server.assert_not_called()
+        self.compute_client.shelve_server.assert_not_called()
+        self.compute_client.shelve_offload_server.assert_not_called()
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
     def test_shelve_with_wait(self, mock_wait_for_status):
@@ -8324,16 +8429,14 @@ class TestServerShelve(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.shelve_server.assert_called_with(
-            self.server.id
-        )
-        self.compute_sdk_client.shelve_offload_server.assert_not_called()
+        self.compute_client.shelve_server.assert_called_with(self.server.id)
+        self.compute_client.shelve_offload_server.assert_not_called()
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=('shelved', 'shelved_offloaded'),
@@ -8353,25 +8456,21 @@ class TestServerShelve(TestServer):
         self.assertIsNone(result)
 
         # one call to retrieve to retrieve the server state before shelving
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name,
             ignore_missing=False,
         )
         # one call to retrieve the server state before offloading
-        self.compute_sdk_client.get_server.assert_called_once_with(
-            self.server.id
-        )
+        self.compute_client.get_server.assert_called_once_with(self.server.id)
         # one call to shelve the server
-        self.compute_sdk_client.shelve_server.assert_called_with(
-            self.server.id
-        )
+        self.compute_client.shelve_server.assert_called_with(self.server.id)
         # one call to shelve offload the server
-        self.compute_sdk_client.shelve_offload_server.assert_called_once_with(
+        self.compute_client.shelve_offload_server.assert_called_once_with(
             self.server.id,
         )
         # one call to wait for the shelve offload to complete
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=('shelved', 'shelved_offloaded'),
@@ -8386,7 +8485,7 @@ class TestServerShow(TestServer):
         self.image_client.get_image.return_value = self.image
 
         self.flavor = compute_fakes.create_one_flavor()
-        self.compute_sdk_client.find_flavor.return_value = self.flavor
+        self.compute_client.find_flavor.return_value = self.flavor
 
         self.topology = {
             'nodes': [{'vcpu_set': [0, 1]}, {'vcpu_set': [2, 3]}],
@@ -8398,14 +8497,14 @@ class TestServerShow(TestServer):
             'tenant_id': 'tenant-id-xxx',
             'addresses': {'public': ['10.20.30.40', '2001:db8::f']},
         }
-        self.compute_sdk_client.get_server_diagnostics.return_value = {
+        self.compute_client.get_server_diagnostics.return_value = {
             'test': 'test'
         }
-        self.server = compute_fakes.create_one_sdk_server(
+        self.server = compute_fakes.create_one_server(
             attrs=server_info,
         )
         self.server.fetch_topology = mock.MagicMock(return_value=self.topology)
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
 
         # Get the command object to test
         self.cmd = server.ShowServer(self.app, None)
@@ -8534,10 +8633,10 @@ class TestServerShow(TestServer):
 
         self.assertTupleEqual(self.columns, columns)
         self.assertTupleEqual(self.data, data)
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False, details=True
         )
-        self.compute_sdk_client.get_server.assert_not_called()
+        self.compute_client.get_server.assert_not_called()
 
     def test_show_embedded_flavor(self):
         # Tests using --os-compute-api-version >= 2.47 where the flavor
@@ -8566,10 +8665,10 @@ class TestServerShow(TestServer):
         # Since the flavor details are in a dict we can't be sure of the
         # ordering so just assert that one of the keys is in the output.
         self.assertIn('original_name', data[columns.index('flavor')]._value)
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False, details=True
         )
-        self.compute_sdk_client.get_server.assert_not_called()
+        self.compute_client.get_server.assert_not_called()
 
     def test_show_diagnostics(self):
         arglist = [
@@ -8587,13 +8686,13 @@ class TestServerShow(TestServer):
 
         self.assertEqual(('test',), columns)
         self.assertEqual(('test',), data)
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False, details=True
         )
-        self.compute_sdk_client.get_server_diagnostics.assert_called_once_with(
+        self.compute_client.get_server_diagnostics.assert_called_once_with(
             self.server
         )
-        self.compute_sdk_client.get_server.assert_not_called()
+        self.compute_client.get_server.assert_not_called()
 
     def test_show_topology(self):
         self.set_compute_api_version('2.78')
@@ -8616,13 +8715,11 @@ class TestServerShow(TestServer):
 
         self.assertCountEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False, details=True
         )
-        self.server.fetch_topology.assert_called_once_with(
-            self.compute_sdk_client
-        )
-        self.compute_sdk_client.get_server.assert_not_called()
+        self.server.fetch_topology.assert_called_once_with(self.compute_client)
+        self.compute_client.get_server.assert_not_called()
 
     def test_show_topology_pre_v278(self):
         self.set_compute_api_version('2.77')
@@ -8641,11 +8738,11 @@ class TestServerShow(TestServer):
         self.assertRaises(
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False, details=True
         )
         self.server.fetch_topology.assert_not_called()
-        self.compute_sdk_client.get_server.assert_not_called()
+        self.compute_client.get_server.assert_not_called()
 
 
 @mock.patch('openstackclient.compute.v2.server.os.system')
@@ -8670,10 +8767,10 @@ class TestServerSsh(TestServer):
                 ],
             },
         }
-        self.server = compute_fakes.create_one_sdk_server(
+        self.server = compute_fakes.create_one_server(
             attrs=self.attrs,
         )
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
 
     def test_server_ssh_no_opts(self, mock_exec):
         arglist = [
@@ -8696,7 +8793,7 @@ class TestServerSsh(TestServer):
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False
         )
         self.assertIsNone(result)
@@ -8729,7 +8826,7 @@ class TestServerSsh(TestServer):
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False
         )
         self.assertIsNone(result)
@@ -8763,7 +8860,7 @@ class TestServerSsh(TestServer):
         with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
             result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.name, ignore_missing=False
         )
         self.assertIsNone(result)
@@ -8791,8 +8888,8 @@ class TestServerStart(TestServerAction):
         self.run_method_with_sdk_servers('start_server', 3)
 
     def test_server_start_with_all_projects(self):
-        server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = server
+        server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = server
 
         arglist = [
             server.id,
@@ -8805,7 +8902,7 @@ class TestServerStart(TestServerAction):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             server.id,
             ignore_missing=False,
             details=False,
@@ -8827,8 +8924,8 @@ class TestServerStop(TestServerAction):
         self.run_method_with_sdk_servers('stop_server', 3)
 
     def test_server_start_with_all_projects(self):
-        server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = server
+        server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = server
 
         arglist = [
             server.id,
@@ -8841,7 +8938,7 @@ class TestServerStop(TestServerAction):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             server.id,
             ignore_missing=False,
             details=False,
@@ -8895,8 +8992,8 @@ class TestServerUnrescue(compute_fakes.T
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.cmd = server.UnrescueServer(self.app, None)
 
@@ -8911,10 +9008,10 @@ class TestServerUnrescue(compute_fakes.T
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.unrescue_server.assert_called_once_with(
+        self.compute_client.unrescue_server.assert_called_once_with(
             self.server
         )
         self.assertIsNone(result)
@@ -8924,8 +9021,8 @@ class TestServerUnset(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         # Get the command object to test
         self.cmd = server.UnsetServer(self.app, None)
@@ -8941,12 +9038,10 @@ class TestServerUnset(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server(
-            self.server.id, ignore_missing=False
-        )
-        self.compute_sdk_client.delete_server_metadata.assert_not_called()
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.remove_tag_from_server.assert_not_called()
+        self.compute_client.find_server(self.server.id, ignore_missing=False)
+        self.compute_client.delete_server_metadata.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.remove_tag_from_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_unset_with_property(self):
@@ -8965,15 +9060,13 @@ class TestServerUnset(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server(
-            self.server.id, ignore_missing=False
-        )
-        self.compute_sdk_client.delete_server_metadata.assert_called_once_with(
+        self.compute_client.find_server(self.server.id, ignore_missing=False)
+        self.compute_client.delete_server_metadata.assert_called_once_with(
             self.server,
             ['key1', 'key2'],
         )
-        self.compute_sdk_client.update_server.assert_not_called()
-        self.compute_sdk_client.remove_tag_from_server.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
+        self.compute_client.remove_tag_from_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_unset_with_description(self):
@@ -8992,14 +9085,12 @@ class TestServerUnset(TestServer):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server(
-            self.server.id, ignore_missing=False
-        )
-        self.compute_sdk_client.update_server.assert_called_once_with(
+        self.compute_client.find_server(self.server.id, ignore_missing=False)
+        self.compute_client.update_server.assert_called_once_with(
             self.server, description=''
         )
-        self.compute_sdk_client.delete_server_metadata.assert_not_called()
-        self.compute_sdk_client.remove_tag_from_server.assert_not_called()
+        self.compute_client.delete_server_metadata.assert_not_called()
+        self.compute_client.remove_tag_from_server.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_unset_with_description_pre_v219(self):
@@ -9042,17 +9133,15 @@ class TestServerUnset(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.find_server(
-            self.server.id, ignore_missing=False
-        )
-        self.compute_sdk_client.remove_tag_from_server.assert_has_calls(
+        self.compute_client.find_server(self.server.id, ignore_missing=False)
+        self.compute_client.remove_tag_from_server.assert_has_calls(
             [
                 mock.call(self.server, 'tag1'),
                 mock.call(self.server, 'tag2'),
             ]
         )
-        self.compute_sdk_client.delete_server_metadata.assert_not_called()
-        self.compute_sdk_client.update_server.assert_not_called()
+        self.compute_client.delete_server_metadata.assert_not_called()
+        self.compute_client.update_server.assert_not_called()
 
     def test_server_unset_with_tag_pre_v226(self):
         self.set_compute_api_version('2.25')
@@ -9082,12 +9171,12 @@ class TestServerUnshelve(TestServer):
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server(
+        self.server = compute_fakes.create_one_server(
             attrs={'status': 'SHELVED'},
         )
 
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.unshelve_server.return_value = None
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.unshelve_server.return_value = None
 
         # Get the command object to test
         self.cmd = server.UnshelveServer(self.app, None)
@@ -9103,11 +9192,11 @@ class TestServerUnshelve(TestServer):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id,
             ignore_missing=False,
         )
-        self.compute_sdk_client.unshelve_server.assert_called_once_with(
+        self.compute_client.unshelve_server.assert_called_once_with(
             self.server.id
         )
 
@@ -9127,11 +9216,11 @@ class TestServerUnshelve(TestServer):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id,
             ignore_missing=False,
         )
-        self.compute_sdk_client.unshelve_server.assert_called_once_with(
+        self.compute_client.unshelve_server.assert_called_once_with(
             self.server.id,
             availability_zone='foo-az',
         )
@@ -9173,11 +9262,11 @@ class TestServerUnshelve(TestServer):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id,
             ignore_missing=False,
         )
-        self.compute_sdk_client.unshelve_server.assert_called_once_with(
+        self.compute_client.unshelve_server.assert_called_once_with(
             self.server.id,
             host='server1',
         )
@@ -9219,11 +9308,11 @@ class TestServerUnshelve(TestServer):
 
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id,
             ignore_missing=False,
         )
-        self.compute_sdk_client.unshelve_server.assert_called_once_with(
+        self.compute_client.unshelve_server.assert_called_once_with(
             self.server.id,
             availability_zone=None,
         )
@@ -9295,15 +9384,13 @@ class TestServerUnshelve(TestServer):
         result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.unshelve_server.assert_called_with(
-            self.server.id
-        )
+        self.compute_client.unshelve_server.assert_called_with(self.server.id)
         mock_wait_for_status.assert_called_once_with(
-            self.compute_sdk_client.get_server,
+            self.compute_client.get_server,
             self.server.id,
             callback=mock.ANY,
             success_status=('active', 'shutoff'),
@@ -9395,7 +9482,7 @@ class TestServerGeneral(TestServer):
         self.image_client.get_image.return_value = _image
 
         _flavor = compute_fakes.create_one_flavor()
-        self.compute_sdk_client.find_flavor.return_value = _flavor
+        self.compute_client.find_flavor.return_value = _flavor
 
         server_info = {
             'image': {'id': _image.id},
@@ -9406,8 +9493,8 @@ class TestServerGeneral(TestServer):
             'properties': '',
             'volumes_attached': [{"id": "6344fe9d-ef20-45b2-91a6"}],
         }
-        _server = compute_fakes.create_one_sdk_server(server_info)
-        self.compute_sdk_client.get_server.return_value = _server
+        _server = compute_fakes.create_one_server(server_info)
+        self.compute_client.get_server.return_value = _server
 
         expected = {
             'OS-DCF:diskConfig': None,
@@ -9458,14 +9545,14 @@ class TestServerGeneral(TestServer):
         }
 
         actual = server._prep_server_detail(
-            self.compute_sdk_client,
+            self.compute_client,
             self.image_client,
             _server,
         )
 
         self.assertCountEqual(expected, actual)
         # this should be called since we need the flavor (< 2.47)
-        self.compute_sdk_client.find_flavor.assert_called_once_with(
+        self.compute_client.find_flavor.assert_called_once_with(
             _flavor.id, ignore_missing=False
         )
 
@@ -9474,7 +9561,7 @@ class TestServerGeneral(TestServer):
         self.image_client.get_image.return_value = _image
 
         _flavor = compute_fakes.create_one_flavor()
-        self.compute_sdk_client.find_flavor.return_value = _flavor
+        self.compute_client.find_flavor.return_value = _flavor
 
         server_info = {
             'image': {'id': _image.id},
@@ -9493,8 +9580,8 @@ class TestServerGeneral(TestServer):
             'properties': '',
             'volumes_attached': [{"id": "6344fe9d-ef20-45b2-91a6"}],
         }
-        _server = compute_fakes.create_one_sdk_server(server_info)
-        self.compute_sdk_client.get_server.return_value = _server
+        _server = compute_fakes.create_one_server(server_info)
+        self.compute_client.get_server.return_value = _server
 
         expected = {
             'OS-DCF:diskConfig': None,
@@ -9545,11 +9632,11 @@ class TestServerGeneral(TestServer):
         }
 
         actual = server._prep_server_detail(
-            self.compute_sdk_client,
+            self.compute_client,
             self.image_client,
             _server,
         )
 
         self.assertCountEqual(expected, actual)
         # this shouldn't be called since we have a full flavor (>= 2.47)
-        self.compute_sdk_client.find_flavor.assert_not_called()
+        self.compute_client.find_flavor.assert_not_called()
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_backup.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_backup.py	2025-07-07 22:41:56.000000000 +0000
@@ -22,24 +22,8 @@ from openstackclient.tests.unit.compute.
 from openstackclient.tests.unit.image.v2 import fakes as image_fakes
 
 
-class TestServerBackup(compute_fakes.TestComputev2):
-    def setup_servers_mock(self, count):
-        servers = compute_fakes.create_sdk_servers(
-            count=count,
-        )
-
-        # This is the return value for compute_client.find_server()
-        self.compute_sdk_client.find_server = compute_fakes.get_servers(
-            servers,
-            0,
-        )
-        return servers
-
-
-class TestServerBackupCreate(TestServerBackup):
-    # Just return whatever Image is testing with these days
+class TestServerBackupCreate(compute_fakes.TestComputev2):
     def image_columns(self, image):
-        # columnlist = tuple(sorted(image.keys()))
         columnlist = (
             'id',
             'name',
@@ -66,42 +50,27 @@ class TestServerBackupCreate(TestServerB
     def setUp(self):
         super().setUp()
 
-        # Get the command object to test
-        self.cmd = server_backup.CreateServerBackup(self.app, None)
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
-    def setup_images_mock(self, count, servers=None):
-        if servers:
-            images = image_fakes.create_images(
-                attrs={
-                    'name': servers[0].name,
-                    'status': 'active',
-                },
-                count=count,
-            )
-        else:
-            images = image_fakes.create_images(
-                attrs={
-                    'status': 'active',
-                },
-                count=count,
-            )
+        self.image = image_fakes.create_one_image(
+            {'name': self.server.name, 'status': 'active'}
+        )
+        self.image_client.find_image.return_value = self.image
 
-        self.image_client.find_image = mock.Mock(side_effect=images)
-        return images
+        # Get the command object to test
+        self.cmd = server_backup.CreateServerBackup(self.app, None)
 
     def test_server_backup_defaults(self):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-
         arglist = [
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('name', None),
             ('type', None),
             ('rotate', None),
             ('wait', False),
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -110,20 +79,17 @@ class TestServerBackupCreate(TestServerB
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.backup_server.assert_called_with(
-            servers[0].id,
-            servers[0].name,
+        self.compute_client.backup_server.assert_called_with(
+            self.server.id,
+            self.server.name,
             '',
             1,
         )
 
-        self.assertEqual(self.image_columns(images[0]), columns)
-        self.assertCountEqual(self.image_data(images[0]), data)
+        self.assertEqual(self.image_columns(self.image), columns)
+        self.assertCountEqual(self.image_data(self.image), data)
 
     def test_server_backup_create_options(self):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-
         arglist = [
             '--name',
             'image',
@@ -131,13 +97,13 @@ class TestServerBackupCreate(TestServerB
             'daily',
             '--rotate',
             '2',
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('name', 'image'),
             ('type', 'daily'),
             ('rotate', 2),
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -146,23 +112,19 @@ class TestServerBackupCreate(TestServerB
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.backup_server.assert_called_with(
-            servers[0].id,
+        self.compute_client.backup_server.assert_called_with(
+            self.server.id,
             'image',
             'daily',
             2,
         )
 
-        self.assertEqual(self.image_columns(images[0]), columns)
-        self.assertCountEqual(self.image_data(images[0]), data)
+        self.assertEqual(self.image_columns(self.image), columns)
+        self.assertCountEqual(self.image_data(self.image), data)
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=False)
     def test_server_backup_wait_fail(self, mock_wait_for_status):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-        self.image_client.get_image = mock.Mock(
-            side_effect=images[0],
-        )
+        self.image_client.get_image.return_value = self.image
 
         arglist = [
             '--name',
@@ -170,13 +132,13 @@ class TestServerBackupCreate(TestServerB
             '--type',
             'daily',
             '--wait',
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('name', 'image'),
             ('type', 'daily'),
             ('wait', True),
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -186,24 +148,21 @@ class TestServerBackupCreate(TestServerB
             parsed_args,
         )
 
-        self.compute_sdk_client.backup_server.assert_called_with(
-            servers[0].id,
+        self.compute_client.backup_server.assert_called_with(
+            self.server.id,
             'image',
             'daily',
             1,
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.image_client.get_image, images[0].id, callback=mock.ANY
+            self.image_client.get_image, self.image.id, callback=mock.ANY
         )
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
     def test_server_backup_wait_ok(self, mock_wait_for_status):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-
         self.image_client.get_image = mock.Mock(
-            side_effect=images[0],
+            side_effect=self.image,
         )
 
         arglist = [
@@ -212,13 +171,13 @@ class TestServerBackupCreate(TestServerB
             '--type',
             'daily',
             '--wait',
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('name', 'image'),
             ('type', 'daily'),
             ('wait', True),
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -227,16 +186,16 @@ class TestServerBackupCreate(TestServerB
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.backup_server.assert_called_with(
-            servers[0].id,
+        self.compute_client.backup_server.assert_called_with(
+            self.server.id,
             'image',
             'daily',
             1,
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.image_client.get_image, images[0].id, callback=mock.ANY
+            self.image_client.get_image, self.image.id, callback=mock.ANY
         )
 
-        self.assertEqual(self.image_columns(images[0]), columns)
-        self.assertCountEqual(self.image_data(images[0]), data)
+        self.assertEqual(self.image_columns(self.image), columns)
+        self.assertCountEqual(self.image_data(self.image), data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_event.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_event.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_event.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_event.py	2025-07-07 22:41:56.000000000 +0000
@@ -22,7 +22,7 @@ from openstackclient.tests.unit.compute.
 
 
 class TestListServerEvent(compute_fakes.TestComputev2):
-    fake_server = compute_fakes.create_one_sdk_server()
+    fake_server = compute_fakes.create_one_server()
     fake_event = compute_fakes.create_one_server_action()
 
     columns = (
@@ -64,8 +64,8 @@ class TestListServerEvent(compute_fakes.
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_server.return_value = self.fake_server
-        self.compute_sdk_client.server_actions.return_value = [
+        self.compute_client.find_server.return_value = self.fake_server
+        self.compute_client.server_actions.return_value = [
             self.fake_event,
         ]
 
@@ -83,11 +83,11 @@ class TestListServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.fake_server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.server_actions.assert_called_with(
+        self.compute_client.server_actions.assert_called_with(
             self.fake_server.id
         )
 
@@ -107,11 +107,11 @@ class TestListServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.fake_server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.server_actions.assert_called_with(
+        self.compute_client.server_actions.assert_called_with(
             self.fake_server.id
         )
 
@@ -134,11 +134,11 @@ class TestListServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.fake_server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.server_actions.assert_called_with(
+        self.compute_client.server_actions.assert_called_with(
             self.fake_server.id,
             changes_since='2016-03-04T06:27:59Z',
         )
@@ -214,11 +214,11 @@ class TestListServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.fake_server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.server_actions.assert_called_with(
+        self.compute_client.server_actions.assert_called_with(
             self.fake_server.id,
             changes_before='2016-03-04T06:27:59Z',
         )
@@ -290,7 +290,7 @@ class TestListServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.server_actions.assert_called_with(
+        self.compute_client.server_actions.assert_called_with(
             self.fake_server.id,
             limit=1,
             paginated=False,
@@ -337,7 +337,7 @@ class TestListServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.server_actions.assert_called_with(
+        self.compute_client.server_actions.assert_called_with(
             self.fake_server.id,
             marker='test_event',
         )
@@ -366,7 +366,7 @@ class TestListServerEvent(compute_fakes.
 
 
 class TestShowServerEvent(compute_fakes.TestComputev2):
-    fake_server = compute_fakes.create_one_sdk_server()
+    fake_server = compute_fakes.create_one_server()
     fake_event = compute_fakes.create_one_server_action()
     columns = (
         'action',
@@ -392,10 +392,8 @@ class TestShowServerEvent(compute_fakes.
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_server.return_value = self.fake_server
-        self.compute_sdk_client.get_server_action.return_value = (
-            self.fake_event
-        )
+        self.compute_client.find_server.return_value = self.fake_server
+        self.compute_client.get_server_action.return_value = self.fake_event
 
         self.cmd = server_event.ShowServerEvent(self.app, None)
 
@@ -412,11 +410,11 @@ class TestShowServerEvent(compute_fakes.
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.fake_server.name,
             ignore_missing=False,
         )
-        self.compute_sdk_client.get_server_action.assert_called_with(
+        self.compute_client.get_server_action.assert_called_with(
             self.fake_event.request_id,
             self.fake_server.id,
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_group.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -55,7 +55,7 @@ class TestServerGroupCreate(TestServerGr
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.create_server_group.return_value = (
+        self.compute_client.create_server_group.return_value = (
             self.fake_server_group
         )
         self.cmd = server_group.CreateServerGroup(self.app, None)
@@ -74,7 +74,7 @@ class TestServerGroupCreate(TestServerGr
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_server_group.assert_called_once_with(
+        self.compute_client.create_server_group.assert_called_once_with(
             name=parsed_args.name,
             policy=parsed_args.policy,
         )
@@ -96,7 +96,7 @@ class TestServerGroupCreate(TestServerGr
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_server_group.assert_called_once_with(
+        self.compute_client.create_server_group.assert_called_once_with(
             name=parsed_args.name,
             policy=parsed_args.policy,
         )
@@ -141,7 +141,7 @@ class TestServerGroupCreate(TestServerGr
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.create_server_group.assert_called_once_with(
+        self.compute_client.create_server_group.assert_called_once_with(
             name=parsed_args.name,
             policy=parsed_args.policy,
             rules=parsed_args.rules,
@@ -179,7 +179,7 @@ class TestServerGroupDelete(TestServerGr
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_server_group.return_value = (
+        self.compute_client.find_server_group.return_value = (
             self.fake_server_group
         )
         self.cmd = server_group.DeleteServerGroup(self.app, None)
@@ -193,10 +193,10 @@ class TestServerGroupDelete(TestServerGr
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_server_group.assert_called_once_with(
+        self.compute_client.find_server_group.assert_called_once_with(
             'affinity_group', ignore_missing=False
         )
-        self.compute_sdk_client.delete_server_group.assert_called_once_with(
+        self.compute_client.delete_server_group.assert_called_once_with(
             self.fake_server_group.id
         )
         self.assertIsNone(result)
@@ -208,21 +208,17 @@ class TestServerGroupDelete(TestServerGr
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.find_server_group.assert_any_call(
+        self.compute_client.find_server_group.assert_any_call(
             'affinity_group', ignore_missing=False
         )
-        self.compute_sdk_client.find_server_group.assert_any_call(
+        self.compute_client.find_server_group.assert_any_call(
             'anti_affinity_group', ignore_missing=False
         )
-        self.compute_sdk_client.delete_server_group.assert_called_with(
+        self.compute_client.delete_server_group.assert_called_with(
             self.fake_server_group.id
         )
-        self.assertEqual(
-            2, self.compute_sdk_client.find_server_group.call_count
-        )
-        self.assertEqual(
-            2, self.compute_sdk_client.delete_server_group.call_count
-        )
+        self.assertEqual(2, self.compute_client.find_server_group.call_count)
+        self.assertEqual(2, self.compute_client.delete_server_group.call_count)
         self.assertIsNone(result)
 
     def test_server_group_delete_no_input(self):
@@ -243,7 +239,7 @@ class TestServerGroupDelete(TestServerGr
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.compute_sdk_client.find_server_group.side_effect = [
+        self.compute_client.find_server_group.side_effect = [
             self.fake_server_group,
             exceptions.CommandError,
         ]
@@ -253,16 +249,14 @@ class TestServerGroupDelete(TestServerGr
         except exceptions.CommandError as e:
             self.assertEqual('1 of 2 server groups failed to delete.', str(e))
 
-        self.compute_sdk_client.find_server_group.assert_any_call(
+        self.compute_client.find_server_group.assert_any_call(
             'affinity_group', ignore_missing=False
         )
-        self.compute_sdk_client.find_server_group.assert_any_call(
+        self.compute_client.find_server_group.assert_any_call(
             'anti_affinity_group', ignore_missing=False
         )
-        self.assertEqual(
-            2, self.compute_sdk_client.find_server_group.call_count
-        )
-        self.compute_sdk_client.delete_server_group.assert_called_once_with(
+        self.assertEqual(2, self.compute_client.find_server_group.call_count)
+        self.compute_client.delete_server_group.assert_called_once_with(
             self.fake_server_group.id
         )
 
@@ -271,7 +265,7 @@ class TestServerGroupList(TestServerGrou
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.server_groups.return_value = [
+        self.compute_client.server_groups.return_value = [
             self.fake_server_group
         ]
         self.cmd = server_group.ListServerGroup(self.app, None)
@@ -287,7 +281,7 @@ class TestServerGroupList(TestServerGrou
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.server_groups.assert_called_once_with()
+        self.compute_client.server_groups.assert_called_once_with()
 
         expected_columns = (
             'ID',
@@ -318,7 +312,7 @@ class TestServerGroupList(TestServerGrou
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.server_groups.assert_called_once_with(
+        self.compute_client.server_groups.assert_called_once_with(
             all_projects=True
         )
 
@@ -359,7 +353,7 @@ class TestServerGroupList(TestServerGrou
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.server_groups.assert_called_once_with(limit=1)
+        self.compute_client.server_groups.assert_called_once_with(limit=1)
 
     def test_server_group_list_with_offset(self):
         arglist = [
@@ -376,7 +370,7 @@ class TestServerGroupList(TestServerGrou
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.server_groups.assert_called_once_with(offset=5)
+        self.compute_client.server_groups.assert_called_once_with(offset=5)
 
     def test_server_group_list_v264(self):
         self.set_compute_api_version('2.64')
@@ -388,7 +382,7 @@ class TestServerGroupList(TestServerGrou
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.server_groups.assert_called_once_with()
+        self.compute_client.server_groups.assert_called_once_with()
 
         expected_columns = (
             'ID',
@@ -419,7 +413,7 @@ class TestServerGroupList(TestServerGrou
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.server_groups.assert_called_once_with(
+        self.compute_client.server_groups.assert_called_once_with(
             all_projects=True
         )
 
@@ -450,7 +444,7 @@ class TestServerGroupShow(TestServerGrou
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.find_server_group.return_value = (
+        self.compute_client.find_server_group.return_value = (
             self.fake_server_group
         )
         self.cmd = server_group.ShowServerGroup(self.app, None)
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_image.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_image.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_image.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_image.py	2025-07-07 22:41:56.000000000 +0000
@@ -21,23 +21,8 @@ from openstackclient.tests.unit.compute.
 from openstackclient.tests.unit.image.v2 import fakes as image_fakes
 
 
-class TestServerImage(compute_fakes.TestComputev2):
-    def setup_servers_mock(self, count):
-        servers = compute_fakes.create_sdk_servers(
-            count=count,
-        )
-
-        # This is the return value for compute_client.find_server()
-        self.compute_sdk_client.find_server = compute_fakes.get_servers(
-            servers,
-            0,
-        )
-        return servers
-
-
-class TestServerImageCreate(TestServerImage):
+class TestServerImageCreate(compute_fakes.TestComputev2):
     def image_columns(self, image):
-        # columnlist = tuple(sorted(image.keys()))
         columnlist = (
             'id',
             'name',
@@ -64,41 +49,24 @@ class TestServerImageCreate(TestServerIm
     def setUp(self):
         super().setUp()
 
-        # Get the command object to test
-        self.cmd = server_image.CreateServerImage(self.app, None)
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
-    def setup_images_mock(self, count, servers=None):
-        if servers:
-            images = image_fakes.create_images(
-                attrs={
-                    'name': servers[0].name,
-                    'status': 'active',
-                },
-                count=count,
-            )
-        else:
-            images = image_fakes.create_images(
-                attrs={
-                    'status': 'active',
-                },
-                count=count,
-            )
-
-        self.image_client.find_image = mock.Mock(side_effect=images)
-        self.compute_sdk_client.create_server_image = mock.Mock(
-            return_value=images[0],
+        self.image = image_fakes.create_one_image(
+            {'name': self.server.name, 'status': 'active'}
         )
-        return images
+        self.image_client.find_image.return_value = self.image
+        self.compute_client.create_server_image.return_value = self.image
 
-    def test_server_image_create_defaults(self):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
+        # Get the command object to test
+        self.cmd = server_image.CreateServerImage(self.app, None)
 
+    def test_server_image_create_defaults(self):
         arglist = [
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -107,29 +75,26 @@ class TestServerImageCreate(TestServerIm
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server_image.assert_called_with(
-            servers[0].id,
-            servers[0].name,
+        self.compute_client.create_server_image.assert_called_with(
+            self.server.id,
+            self.server.name,
             None,
         )
 
-        self.assertEqual(self.image_columns(images[0]), columns)
-        self.assertCountEqual(self.image_data(images[0]), data)
+        self.assertEqual(self.image_columns(self.image), columns)
+        self.assertCountEqual(self.image_data(self.image), data)
 
     def test_server_image_create_options(self):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-
         arglist = [
             '--name',
             'img-nam',
             '--property',
             'key=value',
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('name', 'img-nam'),
-            ('server', servers[0].id),
+            ('server', self.server.id),
             ('properties', {'key': 'value'}),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -139,27 +104,24 @@ class TestServerImageCreate(TestServerIm
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server_image.assert_called_with(
-            servers[0].id,
+        self.compute_client.create_server_image.assert_called_with(
+            self.server.id,
             'img-nam',
             {'key': 'value'},
         )
 
-        self.assertEqual(self.image_columns(images[0]), columns)
-        self.assertCountEqual(self.image_data(images[0]), data)
+        self.assertEqual(self.image_columns(self.image), columns)
+        self.assertCountEqual(self.image_data(self.image), data)
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=False)
     def test_server_create_image_wait_fail(self, mock_wait_for_status):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-
         arglist = [
             '--wait',
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('wait', True),
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -169,28 +131,25 @@ class TestServerImageCreate(TestServerIm
             parsed_args,
         )
 
-        self.compute_sdk_client.create_server_image.assert_called_with(
-            servers[0].id,
-            servers[0].name,
+        self.compute_client.create_server_image.assert_called_with(
+            self.server.id,
+            self.server.name,
             None,
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.image_client.get_image, images[0].id, callback=mock.ANY
+            self.image_client.get_image, self.image.id, callback=mock.ANY
         )
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
     def test_server_create_image_wait_ok(self, mock_wait_for_status):
-        servers = self.setup_servers_mock(count=1)
-        images = self.setup_images_mock(count=1, servers=servers)
-
         arglist = [
             '--wait',
-            servers[0].id,
+            self.server.id,
         ]
         verifylist = [
             ('wait', True),
-            ('server', servers[0].id),
+            ('server', self.server.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -199,15 +158,15 @@ class TestServerImageCreate(TestServerIm
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.create_server_image.assert_called_with(
-            servers[0].id,
-            servers[0].name,
+        self.compute_client.create_server_image.assert_called_with(
+            self.server.id,
+            self.server.name,
             None,
         )
 
         mock_wait_for_status.assert_called_once_with(
-            self.image_client.get_image, images[0].id, callback=mock.ANY
+            self.image_client.get_image, self.image.id, callback=mock.ANY
         )
 
-        self.assertEqual(self.image_columns(images[0]), columns)
-        self.assertCountEqual(self.image_data(images[0]), data)
+        self.assertEqual(self.image_columns(self.image), columns)
+        self.assertCountEqual(self.image_data(self.image), data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_migration.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_migration.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_migration.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_migration.py	2025-07-07 22:41:56.000000000 +0000
@@ -52,11 +52,11 @@ class TestListMigration(compute_fakes.Te
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.migrations = compute_fakes.create_migrations(count=3)
-        self.compute_sdk_client.migrations.return_value = self.migrations
+        self.compute_client.migrations.return_value = self.migrations
 
         self.data = (
             common_utils.get_item_properties(s, self.MIGRATION_FIELDS)
@@ -76,7 +76,7 @@ class TestListMigration(compute_fakes.Te
         # Set expected values
         kwargs = {}
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.assertEqual(self.MIGRATION_COLUMNS, columns)
         self.assertEqual(tuple(self.data), tuple(data))
@@ -108,10 +108,10 @@ class TestListMigration(compute_fakes.Te
             'migration_type': 'migration',
         }
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             'server1', ignore_missing=False
         )
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.assertEqual(self.MIGRATION_COLUMNS, columns)
         self.assertEqual(tuple(self.data), tuple(data))
@@ -169,7 +169,7 @@ class TestListMigrationV223(TestListMigr
             'status': 'migrating',
         }
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.assertEqual(self.MIGRATION_COLUMNS, columns)
         self.assertEqual(tuple(self.data), tuple(data))
@@ -247,7 +247,7 @@ class TestListMigrationV259(TestListMigr
             'changes_since': '2019-08-09T08:03:25Z',
         }
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.assertEqual(self.MIGRATION_COLUMNS, columns)
         self.assertEqual(tuple(self.data), tuple(data))
@@ -376,7 +376,7 @@ class TestListMigrationV266(TestListMigr
             'changes_before': '2019-08-09T08:03:25Z',
         }
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.assertEqual(self.MIGRATION_COLUMNS, columns)
         self.assertEqual(tuple(self.data), tuple(data))
@@ -495,7 +495,7 @@ class TestListMigrationV280(TestListMigr
             'changes_before': "2019-08-09T08:03:25Z",
         }
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.MIGRATION_COLUMNS.insert(
             len(self.MIGRATION_COLUMNS) - 2, "Project"
@@ -572,7 +572,7 @@ class TestListMigrationV280(TestListMigr
             'changes_before': "2019-08-09T08:03:25Z",
         }
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.MIGRATION_COLUMNS.insert(len(self.MIGRATION_COLUMNS) - 2, "User")
         self.MIGRATION_FIELDS.insert(len(self.MIGRATION_FIELDS) - 2, "user_id")
@@ -644,7 +644,7 @@ class TestListMigrationV280(TestListMigr
             'changes_before': "2019-08-09T08:03:25Z",
         }
 
-        self.compute_sdk_client.migrations.assert_called_with(**kwargs)
+        self.compute_client.migrations.assert_called_with(**kwargs)
 
         self.MIGRATION_COLUMNS.insert(
             len(self.MIGRATION_COLUMNS) - 2, "Project"
@@ -694,14 +694,14 @@ class TestServerMigrationShow(compute_fa
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = self.server
 
         self.server_migration = compute_fakes.create_one_server_migration()
-        self.compute_sdk_client.get_server_migration.return_value = (
+        self.compute_client.get_server_migration.return_value = (
             self.server_migration
         )
-        self.compute_sdk_client.server_migrations.return_value = iter(
+        self.compute_client.server_migrations.return_value = iter(
             [self.server_migration]
         )
 
@@ -759,10 +759,10 @@ class TestServerMigrationShow(compute_fa
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.get_server_migration.assert_called_with(
+        self.compute_client.get_server_migration.assert_called_with(
             self.server.id, '2', ignore_missing=False
         )
 
@@ -811,7 +811,7 @@ class TestServerMigrationShow(compute_fa
     def test_server_migration_show_by_uuid(self):
         self.set_compute_api_version('2.59')
 
-        self.compute_sdk_client.server_migrations.return_value = iter(
+        self.compute_client.server_migrations.return_value = iter(
             [self.server_migration]
         )
 
@@ -830,18 +830,18 @@ class TestServerMigrationShow(compute_fa
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.server_migrations.assert_called_with(
+        self.compute_client.server_migrations.assert_called_with(
             self.server.id
         )
-        self.compute_sdk_client.get_server_migration.assert_not_called()
+        self.compute_client.get_server_migration.assert_not_called()
 
     def test_server_migration_show_by_uuid_no_matches(self):
         self.set_compute_api_version('2.59')
 
-        self.compute_sdk_client.server_migrations.return_value = iter([])
+        self.compute_client.server_migrations.return_value = iter([])
 
         arglist = [
             self.server.id,
@@ -897,10 +897,10 @@ class TestServerMigrationAbort(compute_f
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
+        self.server = compute_fakes.create_one_server()
 
         # Return value for utils.find_resource for server.
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
 
         # Get the command object to test
         self.cmd = server_migration.AbortMigration(self.app, None)
@@ -917,10 +917,10 @@ class TestServerMigrationAbort(compute_f
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.abort_server_migration.assert_called_with(
+        self.compute_client.abort_server_migration.assert_called_with(
             '2', self.server.id, ignore_missing=False
         )
         self.assertIsNone(result)
@@ -946,7 +946,7 @@ class TestServerMigrationAbort(compute_f
         self.set_compute_api_version('2.59')
 
         self.server_migration = compute_fakes.create_one_server_migration()
-        self.compute_sdk_client.server_migrations.return_value = iter(
+        self.compute_client.server_migrations.return_value = iter(
             [self.server_migration]
         )
 
@@ -959,13 +959,13 @@ class TestServerMigrationAbort(compute_f
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.server_migrations.assert_called_with(
+        self.compute_client.server_migrations.assert_called_with(
             self.server.id
         )
-        self.compute_sdk_client.abort_server_migration.assert_called_with(
+        self.compute_client.abort_server_migration.assert_called_with(
             self.server_migration.id, self.server.id, ignore_missing=False
         )
         self.assertIsNone(result)
@@ -973,7 +973,7 @@ class TestServerMigrationAbort(compute_f
     def test_server_migration_abort_by_uuid_no_matches(self):
         self.set_compute_api_version('2.59')
 
-        self.compute_sdk_client.server_migrations.return_value = iter([])
+        self.compute_client.server_migrations.return_value = iter([])
 
         arglist = [
             self.server.id,
@@ -1012,10 +1012,10 @@ class TestServerMigrationForceComplete(c
     def setUp(self):
         super().setUp()
 
-        self.server = compute_fakes.create_one_sdk_server()
+        self.server = compute_fakes.create_one_server()
 
         # Return value for utils.find_resource for server.
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
 
         # Get the command object to test
         self.cmd = server_migration.ForceCompleteMigration(self.app, None)
@@ -1032,10 +1032,10 @@ class TestServerMigrationForceComplete(c
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.force_complete_server_migration.assert_called_with(
+        self.compute_client.force_complete_server_migration.assert_called_with(
             '2', self.server.id
         )
         self.assertIsNone(result)
@@ -1061,7 +1061,7 @@ class TestServerMigrationForceComplete(c
         self.set_compute_api_version('2.59')
 
         self.server_migration = compute_fakes.create_one_server_migration()
-        self.compute_sdk_client.server_migrations.return_value = iter(
+        self.compute_client.server_migrations.return_value = iter(
             [self.server_migration]
         )
 
@@ -1074,13 +1074,13 @@ class TestServerMigrationForceComplete(c
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.find_server.assert_called_with(
+        self.compute_client.find_server.assert_called_with(
             self.server.id, ignore_missing=False
         )
-        self.compute_sdk_client.server_migrations.assert_called_with(
+        self.compute_client.server_migrations.assert_called_with(
             self.server.id
         )
-        self.compute_sdk_client.force_complete_server_migration.assert_called_with(
+        self.compute_client.force_complete_server_migration.assert_called_with(
             self.server_migration.id, self.server.id
         )
         self.assertIsNone(result)
@@ -1088,7 +1088,7 @@ class TestServerMigrationForceComplete(c
     def test_server_migration_force_complete_by_uuid_no_matches(self):
         self.set_compute_api_version('2.59')
 
-        self.compute_sdk_client.server_migrations.return_value = iter([])
+        self.compute_client.server_migrations.return_value = iter([])
 
         arglist = [
             self.server.id,
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_volume.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_server_volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_server_volume.py	2025-07-07 22:41:56.000000000 +0000
@@ -31,8 +31,8 @@ class TestServerVolumeList(compute_fakes
             )
         )
 
-        self.compute_sdk_client.find_server.return_value = self.server
-        self.compute_sdk_client.volume_attachments.return_value = (
+        self.compute_client.find_server.return_value = self.server
+        self.compute_client.volume_attachments.return_value = (
             self.volume_attachments
         )
 
@@ -68,7 +68,7 @@ class TestServerVolumeList(compute_fakes
             ),
             tuple(data),
         )
-        self.compute_sdk_client.volume_attachments.assert_called_once_with(
+        self.compute_client.volume_attachments.assert_called_once_with(
             self.server,
         )
 
@@ -114,7 +114,7 @@ class TestServerVolumeList(compute_fakes
             ),
             tuple(data),
         )
-        self.compute_sdk_client.volume_attachments.assert_called_once_with(
+        self.compute_client.volume_attachments.assert_called_once_with(
             self.server,
         )
 
@@ -163,7 +163,7 @@ class TestServerVolumeList(compute_fakes
             ),
             tuple(data),
         )
-        self.compute_sdk_client.volume_attachments.assert_called_once_with(
+        self.compute_client.volume_attachments.assert_called_once_with(
             self.server,
         )
 
@@ -215,7 +215,7 @@ class TestServerVolumeList(compute_fakes
             ),
             tuple(data),
         )
-        self.compute_sdk_client.volume_attachments.assert_called_once_with(
+        self.compute_client.volume_attachments.assert_called_once_with(
             self.server,
         )
 
@@ -225,7 +225,7 @@ class TestServerVolumeUpdate(compute_fak
         super().setUp()
 
         self.server = sdk_fakes.generate_fake_resource(_server.Server)
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
 
         self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
         self.volume_sdk_client.find_volume.return_value = self.volume
@@ -248,7 +248,7 @@ class TestServerVolumeUpdate(compute_fak
         result = self.cmd.take_action(parsed_args)
 
         # This is a no-op
-        self.compute_sdk_client.update_volume_attachment.assert_not_called()
+        self.compute_client.update_volume_attachment.assert_not_called()
         self.assertIsNone(result)
 
     def test_server_volume_update_with_delete_on_termination(self):
@@ -268,7 +268,7 @@ class TestServerVolumeUpdate(compute_fak
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.update_volume_attachment.assert_called_once_with(
+        self.compute_client.update_volume_attachment.assert_called_once_with(
             self.server,
             self.volume,
             delete_on_termination=True,
@@ -292,7 +292,7 @@ class TestServerVolumeUpdate(compute_fak
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.update_volume_attachment.assert_called_once_with(
+        self.compute_client.update_volume_attachment.assert_called_once_with(
             self.server, self.volume, delete_on_termination=False
         )
         self.assertIsNone(result)
@@ -317,7 +317,7 @@ class TestServerVolumeUpdate(compute_fak
             self.cmd.take_action,
             parsed_args,
         )
-        self.compute_sdk_client.update_volume_attachment.assert_not_called()
+        self.compute_client.update_volume_attachment.assert_not_called()
 
     def test_server_volume_update_with_preserve_on_termination_pre_v285(self):
         self.set_compute_api_version('2.84')
@@ -339,4 +339,4 @@ class TestServerVolumeUpdate(compute_fak
             self.cmd.take_action,
             parsed_args,
         )
-        self.compute_sdk_client.update_volume_attachment.assert_not_called()
+        self.compute_client.update_volume_attachment.assert_not_called()
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_service.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_service.py	2025-07-07 22:41:56.000000000 +0000
@@ -30,7 +30,7 @@ class TestServiceDelete(compute_fakes.Te
             sdk_fakes.generate_fake_resources(_service.Service, count=2)
         )
 
-        self.compute_sdk_client.delete_service.return_value = None
+        self.compute_client.delete_service.return_value = None
 
         # Get the command object to test
         self.cmd = service.DeleteService(self.app, None)
@@ -46,7 +46,7 @@ class TestServiceDelete(compute_fakes.Te
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.delete_service.assert_called_with(
+        self.compute_client.delete_service.assert_called_with(
             self.services[0].binary, ignore_missing=False
         )
         self.assertIsNone(result)
@@ -65,7 +65,7 @@ class TestServiceDelete(compute_fakes.Te
         calls = []
         for s in self.services:
             calls.append(mock.call(s.binary, ignore_missing=False))
-        self.compute_sdk_client.delete_service.assert_has_calls(calls)
+        self.compute_client.delete_service.assert_has_calls(calls)
         self.assertIsNone(result)
 
     def test_multi_services_delete_with_exception(self):
@@ -77,7 +77,7 @@ class TestServiceDelete(compute_fakes.Te
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         delete_mock_result = [None, exceptions.CommandError]
-        self.compute_sdk_client.delete_service = mock.Mock(
+        self.compute_client.delete_service = mock.Mock(
             side_effect=delete_mock_result
         )
 
@@ -89,10 +89,10 @@ class TestServiceDelete(compute_fakes.Te
                 '1 of 2 compute services failed to delete.', str(e)
             )
 
-        self.compute_sdk_client.delete_service.assert_any_call(
+        self.compute_client.delete_service.assert_any_call(
             self.services[0].binary, ignore_missing=False
         )
-        self.compute_sdk_client.delete_service.assert_any_call(
+        self.compute_client.delete_service.assert_any_call(
             'unexist_service', ignore_missing=False
         )
 
@@ -103,7 +103,7 @@ class TestServiceList(compute_fakes.Test
 
         self.service = sdk_fakes.generate_fake_resource(_service.Service)
 
-        self.compute_sdk_client.services.return_value = [self.service]
+        self.compute_client.services.return_value = [self.service]
 
         # Get the command object to test
         self.cmd = service.ListService(self.app, None)
@@ -126,7 +126,7 @@ class TestServiceList(compute_fakes.Test
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.services.assert_called_with(
+        self.compute_client.services.assert_called_with(
             host=self.service.host,
             binary=self.service.binary,
         )
@@ -175,7 +175,7 @@ class TestServiceList(compute_fakes.Test
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.services.assert_called_with(
+        self.compute_client.services.assert_called_with(
             host=self.service.host,
             binary=self.service.binary,
         )
@@ -228,7 +228,7 @@ class TestServiceList(compute_fakes.Test
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.services.assert_called_with(
+        self.compute_client.services.assert_called_with(
             host=self.service.host,
             binary=self.service.binary,
         )
@@ -269,8 +269,8 @@ class TestServiceSet(compute_fakes.TestC
 
         self.service = sdk_fakes.generate_fake_resource(_service.Service)
 
-        self.compute_sdk_client.enable_service.return_value = self.service
-        self.compute_sdk_client.disable_service.return_value = self.service
+        self.compute_client.enable_service.return_value = self.service
+        self.compute_client.disable_service.return_value = self.service
 
         self.cmd = service.SetService(self.app, None)
 
@@ -286,8 +286,8 @@ class TestServiceSet(compute_fakes.TestC
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.enable_service.assert_not_called()
-        self.compute_sdk_client.disable_service.assert_not_called()
+        self.compute_client.enable_service.assert_not_called()
+        self.compute_client.disable_service.assert_not_called()
         self.assertIsNone(result)
 
     def test_service_set_enable(self):
@@ -305,7 +305,7 @@ class TestServiceSet(compute_fakes.TestC
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.enable_service.assert_called_with(
+        self.compute_client.enable_service.assert_called_with(
             None, self.service.host, self.service.binary
         )
         self.assertIsNone(result)
@@ -325,7 +325,7 @@ class TestServiceSet(compute_fakes.TestC
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.disable_service.assert_called_with(
+        self.compute_client.disable_service.assert_called_with(
             None, self.service.host, self.service.binary, None
         )
         self.assertIsNone(result)
@@ -349,7 +349,7 @@ class TestServiceSet(compute_fakes.TestC
 
         result = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.disable_service.assert_called_with(
+        self.compute_client.disable_service.assert_called_with(
             None, self.service.host, self.service.binary, reason
         )
         self.assertIsNone(result)
@@ -419,11 +419,11 @@ class TestServiceSet(compute_fakes.TestC
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.update_service_forced_down.assert_called_once_with(
+        self.compute_client.update_service_forced_down.assert_called_once_with(
             None, self.service.host, self.service.binary, False
         )
-        self.assertNotCalled(self.compute_sdk_client.enable_service)
-        self.assertNotCalled(self.compute_sdk_client.disable_service)
+        self.assertNotCalled(self.compute_client.enable_service)
+        self.assertNotCalled(self.compute_client.disable_service)
         self.assertIsNone(result)
 
     def test_service_set_state_down(self):
@@ -441,11 +441,11 @@ class TestServiceSet(compute_fakes.TestC
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.update_service_forced_down.assert_called_once_with(
+        self.compute_client.update_service_forced_down.assert_called_once_with(
             None, self.service.host, self.service.binary, True
         )
-        self.assertNotCalled(self.compute_sdk_client.enable_service)
-        self.assertNotCalled(self.compute_sdk_client.disable_service)
+        self.assertNotCalled(self.compute_client.enable_service)
+        self.assertNotCalled(self.compute_client.disable_service)
         self.assertIsNone(result)
 
     def test_service_set_enable_and_state_down(self):
@@ -465,10 +465,10 @@ class TestServiceSet(compute_fakes.TestC
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.enable_service.assert_called_once_with(
+        self.compute_client.enable_service.assert_called_once_with(
             None, self.service.host, self.service.binary
         )
-        self.compute_sdk_client.update_service_forced_down.assert_called_once_with(
+        self.compute_client.update_service_forced_down.assert_called_once_with(
             None, self.service.host, self.service.binary, True
         )
         self.assertIsNone(result)
@@ -491,12 +491,12 @@ class TestServiceSet(compute_fakes.TestC
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         with mock.patch.object(
-            self.compute_sdk_client, 'enable_service', side_effect=Exception()
+            self.compute_client, 'enable_service', side_effect=Exception()
         ):
             self.assertRaises(
                 exceptions.CommandError, self.cmd.take_action, parsed_args
             )
-            self.compute_sdk_client.update_service_forced_down.assert_called_once_with(
+            self.compute_client.update_service_forced_down.assert_called_once_with(
                 None, self.service.host, self.service.binary, True
             )
 
@@ -519,14 +519,12 @@ class TestServiceSet(compute_fakes.TestC
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
-        self.compute_sdk_client.services.return_value = [
-            mock.Mock(id=service_id)
-        ]
+        self.compute_client.services.return_value = [mock.Mock(id=service_id)]
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.disable_service.assert_called_once_with(
+        self.compute_client.disable_service.assert_called_once_with(
             service_id, self.service.host, self.service.binary, None
         )
-        self.compute_sdk_client.update_service_forced_down.assert_called_once_with(
+        self.compute_client.update_service_forced_down.assert_called_once_with(
             service_id, self.service.host, self.service.binary, True
         )
         self.assertIsNone(result)
@@ -552,11 +550,9 @@ class TestServiceSet(compute_fakes.TestC
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
-        self.compute_sdk_client.services.return_value = [
-            mock.Mock(id=service_id)
-        ]
+        self.compute_client.services.return_value = [mock.Mock(id=service_id)]
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.disable_service.assert_called_once_with(
+        self.compute_client.disable_service.assert_called_once_with(
             service_id, self.service.host, self.service.binary, reason
         )
         self.assertIsNone(result)
@@ -580,25 +576,23 @@ class TestServiceSet(compute_fakes.TestC
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
-        self.compute_sdk_client.services.return_value = [
-            mock.Mock(id=service_id)
-        ]
+        self.compute_client.services.return_value = [mock.Mock(id=service_id)]
         result = self.cmd.take_action(parsed_args)
-        self.compute_sdk_client.enable_service.assert_called_once_with(
+        self.compute_client.enable_service.assert_called_once_with(
             service_id, self.service.host, self.service.binary
         )
-        self.compute_sdk_client.update_service_forced_down.assert_called_once_with(
+        self.compute_client.update_service_forced_down.assert_called_once_with(
             service_id, self.service.host, self.service.binary, False
         )
         self.assertIsNone(result)
 
     def test_service_set_find_service_by_host_and_binary_no_results(self):
         # Tests that no compute services are found by host and binary.
-        self.compute_sdk_client.services.return_value = []
+        self.compute_client.services.return_value = []
         ex = self.assertRaises(
             exceptions.CommandError,
             self.cmd._find_service_by_host_and_binary,
-            self.compute_sdk_client,
+            self.compute_client,
             'fake-host',
             'nova-compute',
         )
@@ -610,14 +604,14 @@ class TestServiceSet(compute_fakes.TestC
 
     def test_service_set_find_service_by_host_and_binary_many_results(self):
         # Tests that more than one compute service is found by host and binary.
-        self.compute_sdk_client.services.return_value = [
+        self.compute_client.services.return_value = [
             mock.Mock(),
             mock.Mock(),
         ]
         ex = self.assertRaises(
             exceptions.CommandError,
             self.cmd._find_service_by_host_and_binary,
-            self.compute_sdk_client,
+            self.compute_client,
             'fake-host',
             'nova-compute',
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/compute/v2/test_usage.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_usage.py
--- 7.4.0-3/openstackclient/tests/unit/compute/v2/test_usage.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/compute/v2/test_usage.py	2025-07-07 22:41:56.000000000 +0000
@@ -58,7 +58,7 @@ class TestUsageList(TestUsage):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.usages.return_value = self.usages
+        self.compute_client.usages.return_value = self.usages
 
         self.projects_mock.list.return_value = [self.project]
         # Get the command object to test
@@ -97,7 +97,7 @@ class TestUsageList(TestUsage):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.projects_mock.list.assert_called_with()
-        self.compute_sdk_client.usages.assert_called_with(
+        self.compute_client.usages.assert_called_with(
             start=datetime.datetime(2016, 11, 11, 0, 0),
             end=datetime.datetime(2016, 12, 20, 0, 0),
             detailed=True,
@@ -118,7 +118,7 @@ class TestUsageList(TestUsage):
         columns, data = self.cmd.take_action(parsed_args)
 
         self.projects_mock.list.assert_called_with()
-        self.compute_sdk_client.usages.assert_has_calls(
+        self.compute_client.usages.assert_has_calls(
             [mock.call(start=mock.ANY, end=mock.ANY, detailed=True)]
         )
         self.assertCountEqual(self.columns, columns)
@@ -151,7 +151,7 @@ class TestUsageShow(TestUsage):
     def setUp(self):
         super().setUp()
 
-        self.compute_sdk_client.get_usage.return_value = self.usage
+        self.compute_client.get_usage.return_value = self.usage
 
         self.projects_mock.get.return_value = self.project
         # Get the command object to test
@@ -194,7 +194,7 @@ class TestUsageShow(TestUsage):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.compute_sdk_client.get_usage.assert_called_with(
+        self.compute_client.get_usage.assert_called_with(
             project=self.project.id,
             start=datetime.datetime(2016, 11, 11, 0, 0),
             end=datetime.datetime(2016, 12, 20, 0, 0),
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v2_0/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v2_0/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v2_0/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v2_0/fakes.py	2025-07-07 22:41:56.000000000 +0000
@@ -228,7 +228,7 @@ class FakeExtension:
         extension_info = {
             'name': 'name-' + uuid.uuid4().hex,
             'namespace': (
-                'http://docs.openstack.org/identity/' 'api/ext/OS-KSCRUD/v1.0'
+                'http://docs.openstack.org/identity/api/ext/OS-KSCRUD/v1.0'
             ),
             'description': 'description-' + uuid.uuid4().hex,
             'updated': '2013-07-07T12:00:0-00:00',
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_access_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_access_rule.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_access_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_access_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -77,9 +77,7 @@ class TestAccessRuleDelete(identity_fake
             self.cmd.take_action(parsed_args)
             self.fail('CommandError should be raised.')
         except exceptions.CommandError as e:
-            self.assertEqual(
-                '1 of 2 access rules failed to' ' delete.', str(e)
-            )
+            self.assertEqual('1 of 2 access rules failed to delete.', str(e))
 
         calls = []
         for a in arglist:
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_application_credential.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_application_credential.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_application_credential.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_application_credential.py	2025-07-07 22:41:56.000000000 +0000
@@ -24,24 +24,13 @@ from openstack.identity.v3 import (
     application_credential as _application_credential,
 )
 from openstack.identity.v3 import role as _role
+from openstack.identity.v3 import user as _user
 from openstack.test import fakes as sdk_fakes
 from openstackclient.identity.v3 import application_credential
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 
 
 class TestApplicationCredentialCreate(identity_fakes.TestIdentityv3):
-    columns = (
-        'id',
-        'name',
-        'description',
-        'project_id',
-        'roles',
-        'unrestricted',
-        'access_rules',
-        'expires_at',
-        'secret',
-    )
-
     def setUp(self):
         super().setUp()
 
@@ -51,12 +40,25 @@ class TestApplicationCredentialCreate(id
             roles=[],
         )
 
-        self.datalist = (
+        self.columns = (
+            'ID',
+            'Name',
+            'Description',
+            'Project ID',
+            'Roles',
+            'Unrestricted',
+            'Access Rules',
+            'Expires At',
+            'Secret',
+        )
+        self.data = (
             self.application_credential.id,
             self.application_credential.name,
             self.application_credential.description,
             self.application_credential.project_id,
-            self.application_credential.roles,
+            application_credential.RolesColumn(
+                self.application_credential.roles
+            ),
             self.application_credential.unrestricted,
             self.application_credential.access_rules,
             self.application_credential.expires_at,
@@ -100,7 +102,7 @@ class TestApplicationCredentialCreate(id
         )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, data)
+        self.assertEqual(self.data, data)
 
     def test_application_credential_create_with_options(self):
         name = self.application_credential.name
@@ -146,7 +148,7 @@ class TestApplicationCredentialCreate(id
         )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, data)
+        self.assertEqual(self.data, data)
 
     def test_application_credential_create_with_access_rules_string(self):
         name = self.application_credential.name
@@ -190,7 +192,7 @@ class TestApplicationCredentialCreate(id
         )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, data)
+        self.assertEqual(self.data, data)
 
     @mock.patch('openstackclient.identity.v3.application_credential.json.load')
     @mock.patch('openstackclient.identity.v3.application_credential.open')
@@ -230,7 +232,7 @@ class TestApplicationCredentialCreate(id
         )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, data)
+        self.assertEqual(self.data, data)
 
 
 class TestApplicationCredentialDelete(identity_fakes.TestIdentityv3):
@@ -295,7 +297,7 @@ class TestApplicationCredentialDelete(id
             self.fail('CommandError should be raised.')
         except exceptions.CommandError as e:
             self.assertEqual(
-                '1 of 2 application credentials failed to' ' delete.', str(e)
+                '1 of 2 application credentials failed to delete.', str(e)
             )
 
         calls = []
@@ -325,6 +327,33 @@ class TestApplicationCredentialList(iden
         self.identity_sdk_client.application_credentials.return_value = [
             self.application_credential
         ]
+        self.user = sdk_fakes.generate_fake_resource(resource_type=_user.User)
+        self.identity_sdk_client.find_user.return_value = self.user
+
+        self.columns = (
+            'ID',
+            'Name',
+            'Description',
+            'Project ID',
+            'Roles',
+            'Unrestricted',
+            'Access Rules',
+            'Expires At',
+        )
+        self.data = (
+            (
+                self.application_credential.id,
+                self.application_credential.name,
+                self.application_credential.description,
+                self.application_credential.project_id,
+                application_credential.RolesColumn(
+                    self.application_credential.roles
+                ),
+                self.application_credential.unrestricted,
+                self.application_credential.access_rules,
+                self.application_credential.expires_at,
+            ),
+        )
 
         # Get the command object to test
         self.cmd = application_credential.ListApplicationCredential(
@@ -339,39 +368,35 @@ class TestApplicationCredentialList(iden
         conn = self.app.client_manager.sdk_connection
         user_id = conn.config.get_auth().get_user_id(conn.identity)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, tuple(data))
+
+        self.identity_sdk_client.find_user.assert_not_called()
         self.identity_sdk_client.application_credentials.assert_called_with(
             user=user_id
         )
 
-        collist = (
-            'ID',
-            'Name',
-            'Description',
-            'Project ID',
-            'Roles',
-            'Unrestricted',
-            'Access Rules',
-            'Expires At',
+    def test_application_credential_list_user(self):
+        arglist = ['--user', self.user.name]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        conn = self.app.client_manager.sdk_connection
+        conn.config.get_auth().get_user_id(conn.identity)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, tuple(data))
+
+        self.identity_sdk_client.find_user.assert_called_once_with(
+            name_or_id=self.user.name, ignore_missing=False
         )
-        self.assertEqual(collist, columns)
-        datalist = (
-            (
-                self.application_credential.id,
-                self.application_credential.name,
-                self.application_credential.description,
-                self.application_credential.project_id,
-                self.application_credential.roles,
-                self.application_credential.unrestricted,
-                self.application_credential.access_rules,
-                self.application_credential.expires_at,
-            ),
+        self.identity_sdk_client.application_credentials.assert_called_with(
+            user=self.user.id
         )
-        self.assertEqual(datalist, tuple(data))
 
 
 class TestApplicationCredentialShow(identity_fakes.TestIdentityv3):
@@ -386,6 +411,29 @@ class TestApplicationCredentialShow(iden
             self.application_credential
         )
 
+        self.columns = (
+            'ID',
+            'Name',
+            'Description',
+            'Project ID',
+            'Roles',
+            'Unrestricted',
+            'Access Rules',
+            'Expires At',
+        )
+        self.data = (
+            self.application_credential.id,
+            self.application_credential.name,
+            self.application_credential.description,
+            self.application_credential.project_id,
+            application_credential.RolesColumn(
+                self.application_credential.roles
+            ),
+            self.application_credential.unrestricted,
+            self.application_credential.access_rules,
+            self.application_credential.expires_at,
+        )
+
         # Get the command object to test
         self.cmd = application_credential.ShowApplicationCredential(
             self.app, None
@@ -412,25 +460,5 @@ class TestApplicationCredentialShow(iden
             user_id, self.application_credential.id
         )
 
-        collist = (
-            'id',
-            'name',
-            'description',
-            'project_id',
-            'roles',
-            'unrestricted',
-            'access_rules',
-            'expires_at',
-        )
-        self.assertEqual(collist, columns)
-        datalist = (
-            self.application_credential.id,
-            self.application_credential.name,
-            self.application_credential.description,
-            self.application_credential.project_id,
-            self.application_credential.roles,
-            self.application_credential.unrestricted,
-            self.application_credential.access_rules,
-            self.application_credential.expires_at,
-        )
-        self.assertEqual(datalist, data)
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_domain.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_domain.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_domain.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_domain.py	2025-07-07 22:41:56.000000000 +0000
@@ -10,33 +10,32 @@
 #   License for the specific language governing permissions and limitations
 #   under the License.
 
+from openstack.identity.v3 import domain as _domain
+from openstack.test import fakes as sdk_fakes
 from openstackclient.identity.v3 import domain
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 
 
-class TestDomain(identity_fakes.TestIdentityv3):
-    def setUp(self):
-        super().setUp()
-
-        # Get a shortcut to the DomainManager Mock
-        self.domains_mock = self.identity_client.domains
-        self.domains_mock.reset_mock()
-
-
-class TestDomainCreate(TestDomain):
-    columns = ('description', 'enabled', 'id', 'name', 'tags')
+class TestDomainCreate(identity_fakes.TestIdentityv3):
+    columns = (
+        'id',
+        'name',
+        'enabled',
+        'description',
+        'options',
+    )
 
     def setUp(self):
         super().setUp()
 
-        self.domain = identity_fakes.FakeDomain.create_one_domain()
-        self.domains_mock.create.return_value = self.domain
+        self.domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+        self.identity_sdk_client.create_domain.return_value = self.domain
         self.datalist = (
-            self.domain.description,
-            True,
             self.domain.id,
             self.domain.name,
-            self.domain.tags,
+            self.domain.is_enabled,
+            self.domain.description,
+            self.domain.options,
         )
 
         # Get the command object to test
@@ -61,9 +60,9 @@ class TestDomainCreate(TestDomain):
             'name': self.domain.name,
             'description': None,
             'options': {},
-            'enabled': True,
+            'is_enabled': True,
         }
-        self.domains_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_domain.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
@@ -90,9 +89,9 @@ class TestDomainCreate(TestDomain):
             'name': self.domain.name,
             'description': 'new desc',
             'options': {},
-            'enabled': True,
+            'is_enabled': True,
         }
-        self.domains_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_domain.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
@@ -103,7 +102,7 @@ class TestDomainCreate(TestDomain):
             self.domain.name,
         ]
         verifylist = [
-            ('enable', True),
+            ('is_enabled', True),
             ('name', self.domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -118,9 +117,9 @@ class TestDomainCreate(TestDomain):
             'name': self.domain.name,
             'description': None,
             'options': {},
-            'enabled': True,
+            'is_enabled': True,
         }
-        self.domains_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_domain.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
@@ -131,7 +130,7 @@ class TestDomainCreate(TestDomain):
             self.domain.name,
         ]
         verifylist = [
-            ('disable', True),
+            ('is_enabled', False),
             ('name', self.domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -146,9 +145,9 @@ class TestDomainCreate(TestDomain):
             'name': self.domain.name,
             'description': None,
             'options': {},
-            'enabled': False,
+            'is_enabled': False,
         }
-        self.domains_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_domain.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
@@ -174,9 +173,9 @@ class TestDomainCreate(TestDomain):
             'name': self.domain.name,
             'description': None,
             'options': {'immutable': True},
-            'enabled': True,
+            'is_enabled': True,
         }
-        self.domains_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_domain.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
@@ -187,7 +186,7 @@ class TestDomainCreate(TestDomain):
             self.domain.name,
         ]
         verifylist = [
-            ('no_immutable', True),
+            ('immutable', False),
             ('name', self.domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -202,23 +201,23 @@ class TestDomainCreate(TestDomain):
             'name': self.domain.name,
             'description': None,
             'options': {'immutable': False},
-            'enabled': True,
+            'is_enabled': True,
         }
-        self.domains_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_domain.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
 
 
-class TestDomainDelete(TestDomain):
-    domain = identity_fakes.FakeDomain.create_one_domain()
+class TestDomainDelete(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     def setUp(self):
         super().setUp()
 
         # This is the return value for utils.find_resource()
-        self.domains_mock.get.return_value = self.domain
-        self.domains_mock.delete.return_value = None
+        self.identity_sdk_client.find_domain.return_value = self.domain
+        self.identity_sdk_client.delete_domain.return_value = None
 
         # Get the command object to test
         self.cmd = domain.DeleteDomain(self.app, None)
@@ -234,19 +233,35 @@ class TestDomainDelete(TestDomain):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.domains_mock.delete.assert_called_with(
+        self.identity_sdk_client.delete_domain.assert_called_with(
             self.domain.id,
         )
         self.assertIsNone(result)
 
 
-class TestDomainList(TestDomain):
-    domain = identity_fakes.FakeDomain.create_one_domain()
+class TestDomainList(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(
+        resource_type=_domain.Domain, is_enabled=True
+    )
+    columns = (
+        'ID',
+        'Name',
+        'Enabled',
+        'Description',
+    )
 
     def setUp(self):
         super().setUp()
 
-        self.domains_mock.list.return_value = [self.domain]
+        self.identity_sdk_client.domains.return_value = [self.domain]
+        self.datalist = (
+            (
+                self.domain.id,
+                self.domain.name,
+                self.domain.is_enabled,
+                self.domain.description,
+            ),
+        )
 
         # Get the command object to test
         self.cmd = domain.ListDomain(self.app, None)
@@ -260,19 +275,10 @@ class TestDomainList(TestDomain):
         # returns a tuple containing the column names and an iterable
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
-        self.domains_mock.list.assert_called_with()
+        self.identity_sdk_client.domains.assert_called_with()
 
-        collist = ('ID', 'Name', 'Enabled', 'Description')
-        self.assertEqual(collist, columns)
-        datalist = (
-            (
-                self.domain.id,
-                self.domain.name,
-                True,
-                self.domain.description,
-            ),
-        )
-        self.assertEqual(datalist, tuple(data))
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, tuple(data))
 
     def test_domain_list_with_option_name(self):
         arglist = ['--name', self.domain.name]
@@ -285,23 +291,14 @@ class TestDomainList(TestDomain):
         columns, data = self.cmd.take_action(parsed_args)
 
         kwargs = {'name': self.domain.name}
-        self.domains_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.domains.assert_called_with(**kwargs)
 
-        collist = ('ID', 'Name', 'Enabled', 'Description')
-        self.assertEqual(collist, columns)
-        datalist = (
-            (
-                self.domain.id,
-                self.domain.name,
-                True,
-                self.domain.description,
-            ),
-        )
-        self.assertEqual(datalist, tuple(data))
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, tuple(data))
 
     def test_domain_list_with_option_enabled(self):
         arglist = ['--enabled']
-        verifylist = [('enabled', True)]
+        verifylist = [('is_enabled', True)]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         # In base command class Lister in cliff, abstract method take_action()
@@ -309,31 +306,22 @@ class TestDomainList(TestDomain):
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        kwargs = {'enabled': True}
-        self.domains_mock.list.assert_called_with(**kwargs)
+        kwargs = {'is_enabled': True}
+        self.identity_sdk_client.domains.assert_called_with(**kwargs)
 
-        collist = ('ID', 'Name', 'Enabled', 'Description')
-        self.assertEqual(collist, columns)
-        datalist = (
-            (
-                self.domain.id,
-                self.domain.name,
-                True,
-                self.domain.description,
-            ),
-        )
-        self.assertEqual(datalist, tuple(data))
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, tuple(data))
 
 
-class TestDomainSet(TestDomain):
-    domain = identity_fakes.FakeDomain.create_one_domain()
+class TestDomainSet(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     def setUp(self):
         super().setUp()
 
-        self.domains_mock.get.return_value = self.domain
+        self.identity_sdk_client.find_domain.return_value = self.domain
 
-        self.domains_mock.update.return_value = self.domain
+        self.identity_sdk_client.update_domain.return_value = self.domain
 
         # Get the command object to test
         self.cmd = domain.SetDomain(self.app, None)
@@ -350,7 +338,9 @@ class TestDomainSet(TestDomain):
         result = self.cmd.take_action(parsed_args)
 
         kwargs = {}
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
     def test_domain_set_name(self):
@@ -371,7 +361,9 @@ class TestDomainSet(TestDomain):
         kwargs = {
             'name': 'qwerty',
         }
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
     def test_domain_set_description(self):
@@ -392,7 +384,9 @@ class TestDomainSet(TestDomain):
         kwargs = {
             'description': 'new desc',
         }
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
     def test_domain_set_enable(self):
@@ -401,7 +395,7 @@ class TestDomainSet(TestDomain):
             self.domain.id,
         ]
         verifylist = [
-            ('enable', True),
+            ('is_enabled', True),
             ('domain', self.domain.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -410,9 +404,11 @@ class TestDomainSet(TestDomain):
 
         # Set expected values
         kwargs = {
-            'enabled': True,
+            'is_enabled': True,
         }
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
     def test_domain_set_disable(self):
@@ -421,7 +417,7 @@ class TestDomainSet(TestDomain):
             self.domain.id,
         ]
         verifylist = [
-            ('disable', True),
+            ('is_enabled', False),
             ('domain', self.domain.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -430,9 +426,11 @@ class TestDomainSet(TestDomain):
 
         # Set expected values
         kwargs = {
-            'enabled': False,
+            'is_enabled': False,
         }
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
     def test_domain_set_immutable_option(self):
@@ -452,7 +450,9 @@ class TestDomainSet(TestDomain):
         kwargs = {
             'options': {'immutable': True},
         }
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
     def test_domain_set_no_immutable_option(self):
@@ -461,7 +461,7 @@ class TestDomainSet(TestDomain):
             self.domain.id,
         ]
         verifylist = [
-            ('no_immutable', True),
+            ('immutable', False),
             ('domain', self.domain.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -472,16 +472,34 @@ class TestDomainSet(TestDomain):
         kwargs = {
             'options': {'immutable': False},
         }
-        self.domains_mock.update.assert_called_with(self.domain.id, **kwargs)
+        self.identity_sdk_client.update_domain.assert_called_with(
+            self.domain.id, **kwargs
+        )
         self.assertIsNone(result)
 
 
-class TestDomainShow(TestDomain):
+class TestDomainShow(identity_fakes.TestIdentityv3):
+    columns = (
+        'id',
+        'name',
+        'enabled',
+        'description',
+        'options',
+    )
+
     def setUp(self):
         super().setUp()
 
-        self.domain = identity_fakes.FakeDomain.create_one_domain()
-        self.domains_mock.get.return_value = self.domain
+        self.domain = sdk_fakes.generate_fake_resource(_domain.Domain)
+        self.identity_sdk_client.find_domain.return_value = self.domain
+        self.datalist = (
+            self.domain.id,
+            self.domain.name,
+            self.domain.is_enabled,
+            self.domain.description,
+            self.domain.options,
+        )
+
         # Get the command object to test
         self.cmd = domain.ShowDomain(self.app, None)
 
@@ -501,17 +519,9 @@ class TestDomainShow(TestDomain):
         # returns a two-part tuple with a tuple of column names and a tuple of
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
-        self.domains_mock.get.assert_called_with(
+        self.identity_sdk_client.find_domain.assert_called_with(
             self.domain.id,
         )
 
-        collist = ('description', 'enabled', 'id', 'name', 'tags')
-        self.assertEqual(collist, columns)
-        datalist = (
-            self.domain.description,
-            True,
-            self.domain.id,
-            self.domain.name,
-            self.domain.tags,
-        )
-        self.assertEqual(datalist, data)
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_endpoint.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_endpoint.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_endpoint.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_endpoint.py	2025-07-07 22:41:56.000000000 +0000
@@ -10,6 +10,13 @@
 #   License for the specific language governing permissions and limitations
 #   under the License.
 
+from openstack.identity.v3 import domain as _domain
+from openstack.identity.v3 import endpoint as _endpoint
+from openstack.identity.v3 import project as _project
+from openstack.identity.v3 import region as _region
+from openstack.identity.v3 import service as _service
+from openstack.test import fakes as sdk_fakes
+
 from openstackclient.identity.v3 import endpoint
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 
@@ -37,30 +44,34 @@ class TestEndpoint(identity_fakes.TestId
         self.projects_mock.reset_mock()
 
 
-class TestEndpointCreate(TestEndpoint):
-    service = identity_fakes.FakeService.create_one_service()
-
+class TestEndpointCreate(identity_fakes.TestIdentityv3):
     columns = (
         'enabled',
         'id',
         'interface',
         'region',
+        'region_id',
         'service_id',
+        'url',
         'service_name',
         'service_type',
-        'url',
     )
 
     def setUp(self):
         super().setUp()
 
-        self.endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-            attrs={'service_id': self.service.id}
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.region = sdk_fakes.generate_fake_resource(_region.Region)
+        self.endpoint = sdk_fakes.generate_fake_resource(
+            resource_type=_endpoint.Endpoint,
+            service_id=self.service.id,
+            interface='admin',
+            region_id=self.region.id,
         )
-        self.endpoints_mock.create.return_value = self.endpoint
 
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
+        self.identity_sdk_client.create_endpoint.return_value = self.endpoint
+        self.identity_sdk_client.find_service.return_value = self.service
+        self.identity_sdk_client.get_region.return_value = self.region
 
         # Get the command object to test
         self.cmd = endpoint.CreateEndpoint(self.app, None)
@@ -79,6 +90,9 @@ class TestEndpointCreate(TestEndpoint):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
+        # Fake endpoints come with a region ID by default, so set it to None
+        setattr(self.endpoint, "region_id", None)
+
         # In base command class ShowOne in cliff, abstract method take_action()
         # returns a two-part tuple with a tuple of column names and a tuple of
         # data to be shown.
@@ -86,25 +100,25 @@ class TestEndpointCreate(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'service': self.service.id,
+            'service_id': self.service.id,
             'url': self.endpoint.url,
             'interface': self.endpoint.interface,
-            'enabled': True,
-            'region': None,
+            'is_enabled': True,
         }
 
-        self.endpoints_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_endpoint.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
             True,
             self.endpoint.id,
             self.endpoint.interface,
-            self.endpoint.region,
+            None,
+            None,
             self.service.id,
+            self.endpoint.url,
             self.service.name,
             self.service.type,
-            self.endpoint.url,
         )
         self.assertEqual(datalist, data)
 
@@ -114,14 +128,14 @@ class TestEndpointCreate(TestEndpoint):
             self.endpoint.interface,
             self.endpoint.url,
             '--region',
-            self.endpoint.region,
+            self.region.id,
         ]
         verifylist = [
             ('enabled', True),
             ('service', self.service.id),
             ('interface', self.endpoint.interface),
             ('url', self.endpoint.url),
-            ('region', self.endpoint.region),
+            ('region', self.region.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -132,25 +146,26 @@ class TestEndpointCreate(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'service': self.service.id,
+            'service_id': self.service.id,
             'url': self.endpoint.url,
             'interface': self.endpoint.interface,
-            'enabled': True,
-            'region': self.endpoint.region,
+            'is_enabled': True,
+            'region_id': self.region.id,
         }
 
-        self.endpoints_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_endpoint.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
             True,
             self.endpoint.id,
             self.endpoint.interface,
-            self.endpoint.region,
+            self.region.id,
+            self.region.id,
             self.service.id,
+            self.endpoint.url,
             self.service.name,
             self.service.type,
-            self.endpoint.url,
         )
         self.assertEqual(datalist, data)
 
@@ -169,6 +184,9 @@ class TestEndpointCreate(TestEndpoint):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
+        # Fake endpoints come with a region ID by default, so set it to None
+        setattr(self.endpoint, "region_id", None)
+
         # In base command class ShowOne in cliff, abstract method take_action()
         # returns a two-part tuple with a tuple of column names and a tuple of
         # data to be shown.
@@ -176,25 +194,25 @@ class TestEndpointCreate(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'service': self.service.id,
+            'service_id': self.service.id,
             'url': self.endpoint.url,
             'interface': self.endpoint.interface,
-            'enabled': True,
-            'region': None,
+            'is_enabled': True,
         }
 
-        self.endpoints_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_endpoint.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
             True,
             self.endpoint.id,
             self.endpoint.interface,
-            self.endpoint.region,
+            None,
+            None,
             self.service.id,
+            self.endpoint.url,
             self.service.name,
             self.service.type,
-            self.endpoint.url,
         )
         self.assertEqual(datalist, data)
 
@@ -213,6 +231,10 @@ class TestEndpointCreate(TestEndpoint):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
+        # Fake endpoints come with a region ID by default, so set it to None
+        setattr(self.endpoint, "region_id", None)
+        setattr(self.endpoint, "is_enabled", False)
+
         # In base command class ShowOne in cliff, abstract method take_action()
         # returns a two-part tuple with a tuple of column names and a tuple of
         # data to be shown.
@@ -220,38 +242,37 @@ class TestEndpointCreate(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'service': self.service.id,
+            'service_id': self.service.id,
             'url': self.endpoint.url,
             'interface': self.endpoint.interface,
-            'enabled': False,
-            'region': None,
+            'is_enabled': False,
         }
 
-        self.endpoints_mock.create.assert_called_with(**kwargs)
+        self.identity_sdk_client.create_endpoint.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
-            True,
+            False,
             self.endpoint.id,
             self.endpoint.interface,
-            self.endpoint.region,
+            None,
+            None,
             self.service.id,
+            self.endpoint.url,
             self.service.name,
             self.service.type,
-            self.endpoint.url,
         )
         self.assertEqual(datalist, data)
 
 
-class TestEndpointDelete(TestEndpoint):
-    endpoint = identity_fakes.FakeEndpoint.create_one_endpoint()
-
+class TestEndpointDelete(identity_fakes.TestIdentityv3):
     def setUp(self):
         super().setUp()
 
-        # This is the return value for utils.find_resource(endpoint)
-        self.endpoints_mock.get.return_value = self.endpoint
-        self.endpoints_mock.delete.return_value = None
+        self.endpoint = sdk_fakes.generate_fake_resource(_endpoint.Endpoint)
+
+        self.identity_sdk_client.find_endpoint.return_value = self.endpoint
+        self.identity_sdk_client.delete_endpoint.return_value = None
 
         # Get the command object to test
         self.cmd = endpoint.DeleteEndpoint(self.app, None)
@@ -267,18 +288,13 @@ class TestEndpointDelete(TestEndpoint):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.endpoints_mock.delete.assert_called_with(
+        self.identity_sdk_client.delete_endpoint.assert_called_with(
             self.endpoint.id,
         )
         self.assertIsNone(result)
 
 
-class TestEndpointList(TestEndpoint):
-    service = identity_fakes.FakeService.create_one_service()
-    endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-        attrs={'service_id': service.id}
-    )
-
+class TestEndpointList(identity_fakes.TestIdentityv3):
     columns = (
         'ID',
         'Region',
@@ -292,11 +308,19 @@ class TestEndpointList(TestEndpoint):
     def setUp(self):
         super().setUp()
 
-        self.endpoints_mock.list.return_value = [self.endpoint]
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.region = sdk_fakes.generate_fake_resource(_region.Region)
+        self.endpoint = sdk_fakes.generate_fake_resource(
+            resource_type=_endpoint.Endpoint,
+            service_id=self.service.id,
+            interface='admin',
+            region_id=self.region.id,
+        )
 
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
-        self.services_mock.list.return_value = [self.service]
+        self.identity_sdk_client.endpoints.return_value = [self.endpoint]
+        self.identity_sdk_client.find_service.return_value = self.service
+        self.identity_sdk_client.services.return_value = [self.service]
+        self.identity_sdk_client.get_region.return_value = self.region
 
         # Get the command object to test
         self.cmd = endpoint.ListEndpoint(self.app, None)
@@ -310,13 +334,13 @@ class TestEndpointList(TestEndpoint):
         # returns a tuple containing the column names and an iterable
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
-        self.endpoints_mock.list.assert_called_with()
+        self.identity_sdk_client.endpoints.assert_called_with()
 
         self.assertEqual(self.columns, columns)
         datalist = (
             (
                 self.endpoint.id,
-                self.endpoint.region,
+                self.region.id,
                 self.service.name,
                 self.service.type,
                 True,
@@ -343,15 +367,15 @@ class TestEndpointList(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'service': self.service.id,
+            'service_id': self.service.id,
         }
-        self.endpoints_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.endpoints.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
             (
                 self.endpoint.id,
-                self.endpoint.region,
+                self.region.id,
                 self.service.name,
                 self.service.type,
                 True,
@@ -380,13 +404,13 @@ class TestEndpointList(TestEndpoint):
         kwargs = {
             'interface': self.endpoint.interface,
         }
-        self.endpoints_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.endpoints.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
             (
                 self.endpoint.id,
-                self.endpoint.region,
+                self.region.id,
                 self.service.name,
                 self.service.type,
                 True,
@@ -399,10 +423,10 @@ class TestEndpointList(TestEndpoint):
     def test_endpoint_list_region(self):
         arglist = [
             '--region',
-            self.endpoint.region,
+            self.region.id,
         ]
         verifylist = [
-            ('region', self.endpoint.region),
+            ('region', self.region.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -413,15 +437,15 @@ class TestEndpointList(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'region': self.endpoint.region,
+            'region_id': self.region.id,
         }
-        self.endpoints_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.endpoints.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
         datalist = (
             (
                 self.endpoint.id,
-                self.endpoint.region,
+                self.region.id,
                 self.service.name,
                 self.service.type,
                 True,
@@ -432,13 +456,13 @@ class TestEndpointList(TestEndpoint):
         self.assertEqual(datalist, tuple(data))
 
     def test_endpoint_list_project_with_project_domain(self):
-        project = identity_fakes.FakeProject.create_one_project()
-        domain = identity_fakes.FakeDomain.create_one_domain()
+        project = sdk_fakes.generate_fake_resource(_project.Project)
+        domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
-        self.ep_filter_mock.list_endpoints_for_project.return_value = [
+        self.identity_sdk_client.project_endpoints.return_value = [
             self.endpoint
         ]
-        self.projects_mock.get.return_value = project
+        self.identity_sdk_client.find_project.return_value = project
 
         arglist = ['--project', project.name, '--project-domain', domain.name]
         verifylist = [
@@ -451,7 +475,7 @@ class TestEndpointList(TestEndpoint):
         # returns a tuple containing the column names and an iterable
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
-        self.ep_filter_mock.list_endpoints_for_project.assert_called_with(
+        self.identity_sdk_client.project_endpoints.assert_called_with(
             project=project.id
         )
 
@@ -459,7 +483,7 @@ class TestEndpointList(TestEndpoint):
         datalist = (
             (
                 self.endpoint.id,
-                self.endpoint.region,
+                self.region.id,
                 self.service.name,
                 self.service.type,
                 True,
@@ -470,22 +494,20 @@ class TestEndpointList(TestEndpoint):
         self.assertEqual(datalist, tuple(data))
 
 
-class TestEndpointSet(TestEndpoint):
-    service = identity_fakes.FakeService.create_one_service()
-    endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-        attrs={'service_id': service.id}
-    )
-
+class TestEndpointSet(identity_fakes.TestIdentityv3):
     def setUp(self):
         super().setUp()
 
-        # This is the return value for utils.find_resource(endpoint)
-        self.endpoints_mock.get.return_value = self.endpoint
-
-        self.endpoints_mock.update.return_value = self.endpoint
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.endpoint = sdk_fakes.generate_fake_resource(
+            resource_type=_endpoint.Endpoint,
+            service_id=self.service.id,
+            interface='admin',
+        )
 
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
+        self.identity_sdk_client.find_endpoint.return_value = self.endpoint
+        self.identity_sdk_client.update_endpoint.return_value = self.endpoint
+        self.identity_sdk_client.find_service.return_value = self.service
 
         # Get the command object to test
         self.cmd = endpoint.SetEndpoint(self.app, None)
@@ -501,15 +523,8 @@ class TestEndpointSet(TestEndpoint):
 
         result = self.cmd.take_action(parsed_args)
 
-        kwargs = {
-            'enabled': None,
-            'interface': None,
-            'region': None,
-            'service': None,
-            'url': None,
-        }
-        self.endpoints_mock.update.assert_called_with(
-            self.endpoint.id, **kwargs
+        self.identity_sdk_client.update_endpoint.assert_called_with(
+            self.endpoint.id
         )
         self.assertIsNone(result)
 
@@ -525,13 +540,9 @@ class TestEndpointSet(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'enabled': None,
             'interface': 'public',
-            'url': None,
-            'region': None,
-            'service': None,
         }
-        self.endpoints_mock.update.assert_called_with(
+        self.identity_sdk_client.update_endpoint.assert_called_with(
             self.endpoint.id, **kwargs
         )
         self.assertIsNone(result)
@@ -548,13 +559,9 @@ class TestEndpointSet(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'enabled': None,
-            'interface': None,
             'url': 'http://localhost:5000',
-            'region': None,
-            'service': None,
         }
-        self.endpoints_mock.update.assert_called_with(
+        self.identity_sdk_client.update_endpoint.assert_called_with(
             self.endpoint.id, **kwargs
         )
         self.assertIsNone(result)
@@ -571,13 +578,9 @@ class TestEndpointSet(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'enabled': None,
-            'interface': None,
-            'url': None,
-            'region': None,
-            'service': self.service.id,
+            'service_id': self.service.id,
         }
-        self.endpoints_mock.update.assert_called_with(
+        self.identity_sdk_client.update_endpoint.assert_called_with(
             self.endpoint.id, **kwargs
         )
         self.assertIsNone(result)
@@ -594,13 +597,9 @@ class TestEndpointSet(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'enabled': None,
-            'interface': None,
-            'url': None,
-            'region': 'e-rzzz',
-            'service': None,
+            'region_id': 'e-rzzz',
         }
-        self.endpoints_mock.update.assert_called_with(
+        self.identity_sdk_client.update_endpoint.assert_called_with(
             self.endpoint.id, **kwargs
         )
         self.assertIsNone(result)
@@ -617,13 +616,9 @@ class TestEndpointSet(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'enabled': True,
-            'interface': None,
-            'url': None,
-            'region': None,
-            'service': None,
+            'is_enabled': True,
         }
-        self.endpoints_mock.update.assert_called_with(
+        self.identity_sdk_client.update_endpoint.assert_called_with(
             self.endpoint.id, **kwargs
         )
         self.assertIsNone(result)
@@ -640,31 +635,31 @@ class TestEndpointSet(TestEndpoint):
 
         # Set expected values
         kwargs = {
-            'enabled': False,
-            'interface': None,
-            'url': None,
-            'region': None,
-            'service': None,
+            'is_enabled': False,
         }
-        self.endpoints_mock.update.assert_called_with(
+        self.identity_sdk_client.update_endpoint.assert_called_with(
             self.endpoint.id, **kwargs
         )
         self.assertIsNone(result)
 
 
-class TestEndpointShow(TestEndpoint):
-    service = identity_fakes.FakeService.create_one_service()
-    endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-        attrs={'service_id': service.id}
-    )
-
+class TestEndpointShow(identity_fakes.TestIdentityv3):
     def setUp(self):
         super().setUp()
 
-        self.endpoints_mock.get.return_value = self.endpoint
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.region = sdk_fakes.generate_fake_resource(_region.Region)
+        self.endpoint = sdk_fakes.generate_fake_resource(
+            resource_type=_endpoint.Endpoint,
+            service_id=self.service.id,
+            interface='admin',
+            region_id=self.region.id,
+        )
+
+        self.identity_sdk_client.find_endpoint.return_value = self.endpoint
 
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
+        self.identity_sdk_client.find_service.return_value = self.service
+        self.identity_sdk_client.get_region.return_value = self.region
 
         # Get the command object to test
         self.cmd = endpoint.ShowEndpoint(self.app, None)
@@ -682,7 +677,7 @@ class TestEndpointShow(TestEndpoint):
         # returns a two-part tuple with a tuple of column names and a tuple of
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
-        self.endpoints_mock.get.assert_called_with(
+        self.identity_sdk_client.find_endpoint.assert_called_with(
             self.endpoint.id,
         )
 
@@ -691,82 +686,82 @@ class TestEndpointShow(TestEndpoint):
             'id',
             'interface',
             'region',
+            'region_id',
             'service_id',
+            'url',
             'service_name',
             'service_type',
-            'url',
         )
         self.assertEqual(collist, columns)
         datalist = (
             True,
             self.endpoint.id,
             self.endpoint.interface,
-            self.endpoint.region,
+            self.region.id,
+            self.region.id,
             self.service.id,
+            self.endpoint.url,
             self.service.name,
             self.service.type,
-            self.endpoint.url,
         )
         self.assertEqual(datalist, data)
 
 
 class TestEndpointCreateServiceWithoutName(TestEndpointCreate):
-    service = identity_fakes.FakeService.create_one_service(
-        attrs={'service_name': ''}
+    service = sdk_fakes.generate_fake_resource(
+        resource_type=_service.Service,
+        name='',
+    )
+    region = sdk_fakes.generate_fake_resource(_region.Region)
+    endpoint = sdk_fakes.generate_fake_resource(
+        resource_type=_endpoint.Endpoint,
+        service_id=service.id,
+        interface='admin',
+        region_id=region.id,
     )
 
     def setUp(self):
-        super(TestEndpointCreate, self).setUp()
-
-        self.endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-            attrs={'service_id': self.service.id}
-        )
-
-        self.endpoints_mock.create.return_value = self.endpoint
-
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
+        super().setUp()
 
         # Get the command object to test
         self.cmd = endpoint.CreateEndpoint(self.app, None)
 
 
 class TestEndpointListServiceWithoutName(TestEndpointList):
-    service = identity_fakes.FakeService.create_one_service(
-        attrs={'service_name': ''}
+    service = sdk_fakes.generate_fake_resource(
+        resource_type=_service.Service,
+        name='',
     )
-    endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-        attrs={'service_id': service.id}
+    region = sdk_fakes.generate_fake_resource(_region.Region)
+    endpoint = sdk_fakes.generate_fake_resource(
+        resource_type=_endpoint.Endpoint,
+        service_id=service.id,
+        interface='admin',
+        region_id=region.id,
     )
 
     def setUp(self):
-        super(TestEndpointList, self).setUp()
-
-        self.endpoints_mock.list.return_value = [self.endpoint]
-
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
-        self.services_mock.list.return_value = [self.service]
+        super().setUp()
 
         # Get the command object to test
         self.cmd = endpoint.ListEndpoint(self.app, None)
 
 
 class TestEndpointShowServiceWithoutName(TestEndpointShow):
-    service = identity_fakes.FakeService.create_one_service(
-        attrs={'service_name': ''}
+    service = sdk_fakes.generate_fake_resource(
+        resource_type=_service.Service,
+        name='',
     )
-    endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(
-        attrs={'service_id': service.id}
+    region = sdk_fakes.generate_fake_resource(_region.Region)
+    endpoint = sdk_fakes.generate_fake_resource(
+        resource_type=_endpoint.Endpoint,
+        service_id=service.id,
+        interface='admin',
+        region_id=region.id,
     )
 
     def setUp(self):
-        super(TestEndpointShow, self).setUp()
-
-        self.endpoints_mock.get.return_value = self.endpoint
-
-        # This is the return value for common.find_resource(service)
-        self.services_mock.get.return_value = self.service
+        super().setUp()
 
         # Get the command object to test
         self.cmd = endpoint.ShowEndpoint(self.app, None)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_group.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,45 +14,33 @@
 from unittest import mock
 from unittest.mock import call
 
-from keystoneauth1 import exceptions as ks_exc
+from openstack import exceptions as sdk_exc
+from openstack.identity.v3 import domain as _domain
+from openstack.identity.v3 import group as _group
+from openstack.identity.v3 import user as _user
+from openstack.test import fakes as sdk_fakes
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.identity.v3 import group
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 
 
-class TestGroup(identity_fakes.TestIdentityv3):
+class TestGroupAddUser(identity_fakes.TestIdentityv3):
     def setUp(self):
         super().setUp()
 
-        # Get a shortcut to the DomainManager Mock
-        self.domains_mock = self.identity_client.domains
-        self.domains_mock.reset_mock()
-
-        # Get a shortcut to the GroupManager Mock
-        self.groups_mock = self.identity_client.groups
-        self.groups_mock.reset_mock()
-
-        # Get a shortcut to the UserManager Mock
-        self.users_mock = self.identity_client.users
-        self.users_mock.reset_mock()
-
-
-class TestGroupAddUser(TestGroup):
-    _group = identity_fakes.FakeGroup.create_one_group()
-    users = identity_fakes.FakeUser.create_users(count=2)
-
-    def setUp(self):
-        super().setUp()
+        self._group = sdk_fakes.generate_fake_resource(_group.Group)
+        self.users = tuple(
+            sdk_fakes.generate_fake_resources(_user.User, count=2)
+        )
 
-        self.groups_mock.get.return_value = self._group
-        self.users_mock.get = identity_fakes.FakeUser.get_users(self.users)
-        self.users_mock.add_to_group.return_value = None
+        self.identity_sdk_client.find_group.return_value = self._group
+        self.identity_sdk_client.add_user_to_group.return_value = None
 
         self.cmd = group.AddUserToGroup(self.app, None)
 
     def test_group_add_user(self):
+        self.identity_sdk_client.find_user.return_value = self.users[0]
         arglist = [
             self._group.name,
             self.users[0].name,
@@ -64,12 +52,16 @@ class TestGroupAddUser(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.users_mock.add_to_group.assert_called_once_with(
+        self.identity_sdk_client.add_user_to_group.assert_called_once_with(
             self.users[0].id, self._group.id
         )
         self.assertIsNone(result)
 
     def test_group_add_multi_users(self):
+        self.identity_sdk_client.find_user.side_effect = [
+            self.users[0],
+            self.users[1],
+        ]
         arglist = [
             self._group.name,
             self.users[0].name,
@@ -86,13 +78,13 @@ class TestGroupAddUser(TestGroup):
             call(self.users[0].id, self._group.id),
             call(self.users[1].id, self._group.id),
         ]
-        self.users_mock.add_to_group.assert_has_calls(calls)
+        self.identity_sdk_client.add_user_to_group.assert_has_calls(calls)
         self.assertIsNone(result)
 
     @mock.patch.object(group.LOG, 'error')
     def test_group_add_user_with_error(self, mock_error):
-        self.users_mock.add_to_group.side_effect = [
-            exceptions.CommandError(),
+        self.identity_sdk_client.add_user_to_group.side_effect = [
+            sdk_exc.ResourceNotFound,
             None,
         ]
         arglist = [
@@ -111,20 +103,20 @@ class TestGroupAddUser(TestGroup):
         except exceptions.CommandError as e:
             msg = f"1 of 2 users not added to group {self._group.name}."
             self.assertEqual(msg, str(e))
-        msg = f"{self.users[0].name} not added to group {self._group.name}: "
+        msg = f"{self.users[0].name} not added to group {self._group.name}: {str(sdk_exc.ResourceNotFound())}"
         mock_error.assert_called_once_with(msg)
 
 
-class TestGroupCheckUser(TestGroup):
-    group = identity_fakes.FakeGroup.create_one_group()
-    user = identity_fakes.FakeUser.create_one_user()
-
+class TestGroupCheckUser(identity_fakes.TestIdentityv3):
     def setUp(self):
         super().setUp()
 
-        self.groups_mock.get.return_value = self.group
-        self.users_mock.get.return_value = self.user
-        self.users_mock.check_in_group.return_value = None
+        self.group = sdk_fakes.generate_fake_resource(_group.Group)
+        self.user = sdk_fakes.generate_fake_resource(_user.User)
+
+        self.identity_sdk_client.find_group.return_value = self.group
+        self.identity_sdk_client.find_user.return_value = self.user
+        self.identity_sdk_client.check_user_in_group.return_value = True
 
         self.cmd = group.CheckUserInGroup(self.app, None)
 
@@ -140,16 +132,15 @@ class TestGroupCheckUser(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.users_mock.check_in_group.assert_called_once_with(
+        self.identity_sdk_client.check_user_in_group.assert_called_once_with(
             self.user.id, self.group.id
         )
         self.assertIsNone(result)
 
     def test_group_check_user_server_error(self):
-        def server_error(*args):
-            raise ks_exc.http.InternalServerError
-
-        self.users_mock.check_in_group.side_effect = server_error
+        self.identity_sdk_client.check_user_in_group.side_effect = (
+            sdk_exc.SDKException
+        )
         arglist = [
             self.group.name,
             self.user.name,
@@ -161,12 +152,12 @@ class TestGroupCheckUser(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         self.assertRaises(
-            ks_exc.http.InternalServerError, self.cmd.take_action, parsed_args
+            sdk_exc.SDKException, self.cmd.take_action, parsed_args
         )
 
 
-class TestGroupCreate(TestGroup):
-    domain = identity_fakes.FakeDomain.create_one_domain()
+class TestGroupCreate(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     columns = (
         'description',
@@ -177,23 +168,20 @@ class TestGroupCreate(TestGroup):
 
     def setUp(self):
         super().setUp()
-        self.group = identity_fakes.FakeGroup.create_one_group(
-            attrs={'domain_id': self.domain.id}
+        self.group = sdk_fakes.generate_fake_resource(
+            _group.Group, description=None, domain_id=None
         )
-        self.data = (
-            self.group.description,
-            self.group.domain_id,
-            self.group.id,
-            self.group.name,
+        self.group_with_options = sdk_fakes.generate_fake_resource(
+            _group.Group, domain_id=self.domain.id
         )
 
-        self.groups_mock.create.return_value = self.group
-        self.groups_mock.get.return_value = self.group
-        self.domains_mock.get.return_value = self.domain
+        self.identity_sdk_client.find_group.return_value = self.group
+        self.identity_sdk_client.find_domain.return_value = self.domain
 
         self.cmd = group.CreateGroup(self.app, None)
 
     def test_group_create(self):
+        self.identity_sdk_client.create_group.return_value = self.group
         arglist = [
             self.group.name,
         ]
@@ -203,40 +191,56 @@ class TestGroupCreate(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.groups_mock.create.assert_called_once_with(
+        self.identity_sdk_client.create_group.assert_called_once_with(
             name=self.group.name,
-            domain=None,
-            description=None,
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        datalist = (
+            self.group.description,
+            None,
+            self.group.id,
+            self.group.name,
+        )
+        self.assertEqual(datalist, data)
 
     def test_group_create_with_options(self):
+        self.identity_sdk_client.create_group.return_value = (
+            self.group_with_options
+        )
         arglist = [
             '--domain',
             self.domain.name,
             '--description',
-            self.group.description,
-            self.group.name,
+            self.group_with_options.description,
+            self.group_with_options.name,
         ]
         verifylist = [
             ('domain', self.domain.name),
-            ('description', self.group.description),
-            ('name', self.group.name),
+            ('description', self.group_with_options.description),
+            ('name', self.group_with_options.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.groups_mock.create.assert_called_once_with(
-            name=self.group.name,
-            domain=self.domain.id,
-            description=self.group.description,
+        self.identity_sdk_client.create_group.assert_called_once_with(
+            name=self.group_with_options.name,
+            domain_id=self.domain.id,
+            description=self.group_with_options.description,
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        datalist = (
+            self.group_with_options.description,
+            self.domain.id,
+            self.group_with_options.id,
+            self.group_with_options.name,
+        )
+        self.assertEqual(datalist, data)
 
     def test_group_create_or_show(self):
-        self.groups_mock.create.side_effect = ks_exc.Conflict()
+        self.identity_sdk_client.find_group.return_value = self.group
+        self.identity_sdk_client.create_group.side_effect = (
+            sdk_exc.ConflictException
+        )
         arglist = [
             '--or-show',
             self.group.name,
@@ -248,46 +252,97 @@ class TestGroupCreate(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.groups_mock.get.assert_called_once_with(self.group.name)
+        self.identity_sdk_client.find_group.assert_called_once_with(
+            self.group.name
+        )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        datalist = (
+            self.group.description,
+            None,
+            self.group.id,
+            self.group.name,
+        )
+        self.assertEqual(datalist, data)
 
+    def test_group_create_or_show_with_domain(self):
+        self.identity_sdk_client.find_group.return_value = (
+            self.group_with_options
+        )
+        self.identity_sdk_client.create_group.side_effect = (
+            sdk_exc.ConflictException
+        )
+        arglist = [
+            '--or-show',
+            self.group_with_options.name,
+            '--domain',
+            self.domain.id,
+        ]
+        verifylist = [
+            ('or_show', True),
+            ('name', self.group_with_options.name),
+            ('domain', self.domain.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-class TestGroupDelete(TestGroup):
-    domain = identity_fakes.FakeDomain.create_one_domain()
-    groups = identity_fakes.FakeGroup.create_groups(
-        attrs={'domain_id': domain.id}, count=2
-    )
+        columns, data = self.cmd.take_action(parsed_args)
+        self.identity_sdk_client.find_group.assert_called_once_with(
+            self.group_with_options.name, domain_id=self.domain.id
+        )
+        self.assertEqual(self.columns, columns)
+        datalist = (
+            self.group_with_options.description,
+            self.domain.id,
+            self.group_with_options.id,
+            self.group_with_options.name,
+        )
+        self.assertEqual(datalist, data)
+
+
+class TestGroupDelete(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     def setUp(self):
         super().setUp()
 
-        self.groups_mock.get = identity_fakes.FakeGroup.get_groups(self.groups)
-        self.groups_mock.delete.return_value = None
-        self.domains_mock.get.return_value = self.domain
+        self.group = sdk_fakes.generate_fake_resource(
+            _group.Group,
+            domain_id=None,
+        )
+        self.group_with_domain = sdk_fakes.generate_fake_resource(
+            _group.Group,
+            name=self.group.name,
+            domain_id=self.domain.id,
+        )
+        self.identity_sdk_client.delete_group.return_value = None
+        self.identity_sdk_client.find_domain.return_value = self.domain
 
         self.cmd = group.DeleteGroup(self.app, None)
 
     def test_group_delete(self):
+        self.identity_sdk_client.find_group.return_value = self.group
         arglist = [
-            self.groups[0].id,
+            self.group.id,
         ]
         verifylist = [
-            ('groups', [self.groups[0].id]),
+            ('groups', [self.group.id]),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.groups_mock.get.assert_called_once_with(self.groups[0].id)
-        self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
+        self.identity_sdk_client.find_group.assert_called_once_with(
+            name_or_id=self.group.id, ignore_missing=False
+        )
+        self.identity_sdk_client.delete_group.assert_called_once_with(
+            self.group.id
+        )
         self.assertIsNone(result)
 
     def test_group_multi_delete(self):
-        arglist = []
-        verifylist = []
-
-        for g in self.groups:
-            arglist.append(g.id)
+        self.identity_sdk_client.find_group.side_effect = [
+            self.group,
+            self.group_with_domain,
+        ]
+        arglist = [self.group.id, self.group_with_domain.id]
         verifylist = [
             ('groups', arglist),
         ]
@@ -295,39 +350,50 @@ class TestGroupDelete(TestGroup):
 
         result = self.cmd.take_action(parsed_args)
 
-        calls = []
-        for g in self.groups:
-            calls.append(call(g.id))
-        self.groups_mock.delete.assert_has_calls(calls)
+        self.identity_sdk_client.delete_group.assert_has_calls(
+            [mock.call(self.group.id), mock.call(self.group_with_domain.id)]
+        )
         self.assertIsNone(result)
 
     def test_group_delete_with_domain(self):
-        get_mock_result = [exceptions.CommandError, self.groups[0]]
-        self.groups_mock.get = mock.Mock(side_effect=get_mock_result)
+        self.identity_sdk_client.find_domain.side_effect = [
+            sdk_exc.ForbiddenException
+        ]
+        self.identity_sdk_client.find_group.return_value = (
+            self.group_with_domain
+        )
 
         arglist = [
             '--domain',
-            self.domain.id,
-            self.groups[0].id,
+            self.group_with_domain.domain_id,
+            self.group_with_domain.name,
         ]
         verifylist = [
-            ('domain', self.groups[0].domain_id),
-            ('groups', [self.groups[0].id]),
+            ('domain', self.domain.id),
+            ('groups', [self.group_with_domain.name]),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.groups_mock.get.assert_any_call(
-            self.groups[0].id, domain_id=self.domain.id
+        self.identity_sdk_client.find_group.assert_called_with(
+            name_or_id=self.group_with_domain.name,
+            ignore_missing=False,
+            domain_id=self.domain.id,
+        )
+        self.identity_sdk_client.delete_group.assert_called_once_with(
+            self.group_with_domain.id
         )
-        self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
         self.assertIsNone(result)
 
-    @mock.patch.object(utils, 'find_resource')
-    def test_delete_multi_groups_with_exception(self, find_mock):
-        find_mock.side_effect = [self.groups[0], exceptions.CommandError]
+    def test_delete_multi_groups_with_exception(self):
+        self.identity_sdk_client.find_group.side_effect = [
+            self.group,
+            self.group_with_domain,
+            exceptions.CommandError,
+        ]
         arglist = [
-            self.groups[0].id,
+            self.group.id,
+            self.group_with_domain.id,
             'unexist_group',
         ]
         verifylist = [
@@ -339,45 +405,57 @@ class TestGroupDelete(TestGroup):
             self.cmd.take_action(parsed_args)
             self.fail('CommandError should be raised.')
         except exceptions.CommandError as e:
-            self.assertEqual('1 of 2 groups failed to delete.', str(e))
+            self.assertEqual('1 of 3 groups failed to delete.', str(e))
 
-        find_mock.assert_any_call(self.groups_mock, self.groups[0].id)
-        find_mock.assert_any_call(self.groups_mock, 'unexist_group')
+        self.identity_sdk_client.find_group.assert_has_calls(
+            [
+                mock.call(name_or_id=self.group.id, ignore_missing=False),
+                mock.call(
+                    name_or_id=self.group_with_domain.id, ignore_missing=False
+                ),
+                mock.call(name_or_id='unexist_group', ignore_missing=False),
+            ]
+        )
 
-        self.assertEqual(2, find_mock.call_count)
-        self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
+        self.assertEqual(3, self.identity_sdk_client.find_group.call_count)
+        self.identity_sdk_client.delete_group.assert_has_calls(
+            [
+                mock.call(self.group.id),
+                mock.call(self.group_with_domain.id),
+            ]
+        )
 
 
-class TestGroupList(TestGroup):
-    domain = identity_fakes.FakeDomain.create_one_domain()
-    group = identity_fakes.FakeGroup.create_one_group()
-    user = identity_fakes.FakeUser.create_one_user()
+class TestGroupList(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     columns = (
         'ID',
         'Name',
     )
-    datalist = (
-        (
-            group.id,
-            group.name,
-        ),
-    )
 
     def setUp(self):
         super().setUp()
 
-        self.groups_mock.get.return_value = self.group
-        self.groups_mock.list.return_value = [self.group]
-
-        self.domains_mock.get.return_value = self.domain
+        self.group = sdk_fakes.generate_fake_resource(
+            _group.Group, description=None, domain_id=None
+        )
+        self.group_with_domain = sdk_fakes.generate_fake_resource(
+            _group.Group, domain_id=self.domain.id
+        )
+        self.user = sdk_fakes.generate_fake_resource(_user.User)
 
-        self.users_mock.get.return_value = self.user
+        self.identity_sdk_client.find_user.return_value = self.user
+        self.identity_sdk_client.find_domain.return_value = self.domain
 
         # Get the command object to test
         self.cmd = group.ListGroup(self.app, None)
 
     def test_group_list_no_options(self):
+        self.identity_sdk_client.groups.return_value = [
+            self.group,
+            self.group_with_domain,
+        ]
         arglist = []
         verifylist = []
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -387,18 +465,23 @@ class TestGroupList(TestGroup):
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        # Set expected values
-        kwargs = {
-            'domain': None,
-            'user': None,
-        }
-
-        self.groups_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.groups.assert_called_with()
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, tuple(data))
+        datalist = (
+            (
+                self.group.id,
+                self.group.name,
+            ),
+            (
+                self.group_with_domain.id,
+                self.group_with_domain.name,
+            ),
+        )
+        self.assertEqual(datalist, tuple(data))
 
     def test_group_list_domain(self):
+        self.identity_sdk_client.groups.return_value = [self.group_with_domain]
         arglist = [
             '--domain',
             self.domain.id,
@@ -415,22 +498,51 @@ class TestGroupList(TestGroup):
 
         # Set expected values
         kwargs = {
-            'domain': self.domain.id,
-            'user': None,
+            'domain_id': self.domain.id,
         }
 
-        self.groups_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.groups.assert_called_with(**kwargs)
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, tuple(data))
+        datalist = ((self.group_with_domain.id, self.group_with_domain.name),)
+        self.assertEqual(datalist, tuple(data))
 
     def test_group_list_user(self):
+        self.identity_sdk_client.user_groups.return_value = [self.group]
+        arglist = [
+            '--user',
+            self.user.name,
+        ]
+        verifylist = [
+            ('user', self.user.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # In base command class Lister in cliff, abstract method take_action()
+        # returns a tuple containing the column names and an iterable
+        # containing the data to be listed.
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.identity_sdk_client.user_groups.assert_called_with(self.user.id)
+
+        self.assertEqual(self.columns, columns)
+
+        datalist = ((self.group.id, self.group.name),)
+        self.assertEqual(datalist, tuple(data))
+
+    def test_group_list_user_domain(self):
+        self.identity_sdk_client.user_groups.return_value = [
+            self.group_with_domain
+        ]
         arglist = [
             '--user',
             self.user.name,
+            '--domain',
+            self.domain.name,
         ]
         verifylist = [
             ('user', self.user.name),
+            ('domain', self.domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -441,16 +553,23 @@ class TestGroupList(TestGroup):
 
         # Set expected values
         kwargs = {
-            'domain': None,
-            'user': self.user.id,
+            'domain_id': self.domain.id,
         }
 
-        self.groups_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.user_groups.assert_called_with(
+            self.user.id, **kwargs
+        )
 
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.datalist, tuple(data))
+
+        datalist = ((self.group_with_domain.id, self.group_with_domain.name),)
+        self.assertEqual(datalist, tuple(data))
 
     def test_group_list_long(self):
+        self.identity_sdk_client.groups.return_value = [
+            self.group,
+            self.group_with_domain,
+        ]
         arglist = [
             '--long',
         ]
@@ -464,15 +583,9 @@ class TestGroupList(TestGroup):
         # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        # Set expected values
-        kwargs = {
-            'domain': None,
-            'user': None,
-        }
-
-        self.groups_mock.list.assert_called_with(**kwargs)
+        self.identity_sdk_client.groups.assert_called_with()
 
-        columns = self.columns + (
+        long_columns = self.columns + (
             'Domain ID',
             'Description',
         )
@@ -483,25 +596,33 @@ class TestGroupList(TestGroup):
                 self.group.domain_id,
                 self.group.description,
             ),
+            (
+                self.group_with_domain.id,
+                self.group_with_domain.name,
+                self.group_with_domain.domain_id,
+                self.group_with_domain.description,
+            ),
         )
-        self.assertEqual(columns, columns)
+        self.assertEqual(long_columns, columns)
         self.assertEqual(datalist, tuple(data))
 
 
-class TestGroupRemoveUser(TestGroup):
-    _group = identity_fakes.FakeGroup.create_one_group()
-    users = identity_fakes.FakeUser.create_users(count=2)
-
+class TestGroupRemoveUser(identity_fakes.TestIdentityv3):
     def setUp(self):
         super().setUp()
 
-        self.groups_mock.get.return_value = self._group
-        self.users_mock.get = identity_fakes.FakeUser.get_users(self.users)
-        self.users_mock.remove_from_group.return_value = None
+        self._group = sdk_fakes.generate_fake_resource(_group.Group)
+        self.users = tuple(
+            sdk_fakes.generate_fake_resources(_user.User, count=2)
+        )
+
+        self.identity_sdk_client.find_group.return_value = self._group
+        self.identity_sdk_client.remove_user_from_group.return_value = None
 
         self.cmd = group.RemoveUserFromGroup(self.app, None)
 
     def test_group_remove_user(self):
+        self.identity_sdk_client.find_user.return_value = self.users[0]
         arglist = [
             self._group.id,
             self.users[0].id,
@@ -513,12 +634,16 @@ class TestGroupRemoveUser(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.users_mock.remove_from_group.assert_called_once_with(
+        self.identity_sdk_client.remove_user_from_group.assert_called_once_with(
             self.users[0].id, self._group.id
         )
         self.assertIsNone(result)
 
     def test_group_remove_multi_users(self):
+        self.identity_sdk_client.find_user.side_effect = [
+            self.users[0],
+            self.users[1],
+        ]
         arglist = [
             self._group.name,
             self.users[0].name,
@@ -535,13 +660,13 @@ class TestGroupRemoveUser(TestGroup):
             call(self.users[0].id, self._group.id),
             call(self.users[1].id, self._group.id),
         ]
-        self.users_mock.remove_from_group.assert_has_calls(calls)
+        self.identity_sdk_client.remove_user_from_group.assert_has_calls(calls)
         self.assertIsNone(result)
 
     @mock.patch.object(group.LOG, 'error')
     def test_group_remove_user_with_error(self, mock_error):
-        self.users_mock.remove_from_group.side_effect = [
-            exceptions.CommandError(),
+        self.identity_sdk_client.remove_user_from_group.side_effect = [
+            sdk_exc.ResourceNotFound(),
             None,
         ]
         arglist = [
@@ -560,26 +685,29 @@ class TestGroupRemoveUser(TestGroup):
         except exceptions.CommandError as e:
             msg = f"1 of 2 users not removed from group {self._group.id}."
             self.assertEqual(msg, str(e))
-        msg = f"{self.users[0].id} not removed from group {self._group.id}: "
+        msg = f"{self.users[0].id} not removed from group {self._group.id}: {str(sdk_exc.ResourceNotFound())}"
         mock_error.assert_called_once_with(msg)
 
 
-class TestGroupSet(TestGroup):
-    domain = identity_fakes.FakeDomain.create_one_domain()
-    group = identity_fakes.FakeGroup.create_one_group(
-        attrs={'domain_id': domain.id}
-    )
+class TestGroupSet(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     def setUp(self):
         super().setUp()
+        self.group = sdk_fakes.generate_fake_resource(
+            _group.Group, domain_id=self.domain.id
+        )
+        self.group_with_domain = sdk_fakes.generate_fake_resource(
+            _group.Group, name=self.group.name, domain_id=self.domain.id
+        )
 
-        self.groups_mock.get.return_value = self.group
-        self.domains_mock.get.return_value = self.domain
-        self.groups_mock.update.return_value = None
+        self.identity_sdk_client.find_group.return_value = self.group
+        self.identity_sdk_client.find_domain.return_value = self.domain
 
         self.cmd = group.SetGroup(self.app, None)
 
     def test_group_set_nothing(self):
+        self.identity_sdk_client.update_group.return_value = self.group
         arglist = [
             self.group.id,
         ]
@@ -589,10 +717,13 @@ class TestGroupSet(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.groups_mock.update.assert_called_once_with(self.group.id)
+        self.identity_sdk_client.update_group.assert_called_once_with(
+            self.group.id
+        )
         self.assertIsNone(result)
 
     def test_group_set_name_and_description(self):
+        self.identity_sdk_client.update_group.return_value = self.group
         arglist = [
             '--name',
             'new_name',
@@ -612,36 +743,43 @@ class TestGroupSet(TestGroup):
             'name': 'new_name',
             'description': 'new_description',
         }
-        self.groups_mock.update.assert_called_once_with(
+        self.identity_sdk_client.update_group.assert_called_once_with(
             self.group.id, **kwargs
         )
         self.assertIsNone(result)
 
     def test_group_set_with_domain(self):
-        get_mock_result = [exceptions.CommandError, self.group]
-        self.groups_mock.get = mock.Mock(side_effect=get_mock_result)
-
+        self.identity_sdk_client.find_domain.side_effect = [
+            sdk_exc.ForbiddenException
+        ]
+        self.identity_sdk_client.find_group.return_value = (
+            self.group_with_domain
+        )
         arglist = [
             '--domain',
             self.domain.id,
-            self.group.id,
+            self.group_with_domain.name,
         ]
         verifylist = [
             ('domain', self.domain.id),
-            ('group', self.group.id),
+            ('group', self.group_with_domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.groups_mock.get.assert_any_call(
-            self.group.id, domain_id=self.domain.id
+        self.identity_sdk_client.find_group.assert_called_once_with(
+            name_or_id=self.group_with_domain.name,
+            ignore_missing=False,
+            domain_id=self.domain.id,
+        )
+        self.identity_sdk_client.update_group.assert_called_once_with(
+            self.group_with_domain.id
         )
-        self.groups_mock.update.assert_called_once_with(self.group.id)
         self.assertIsNone(result)
 
 
-class TestGroupShow(TestGroup):
-    domain = identity_fakes.FakeDomain.create_one_domain()
+class TestGroupShow(identity_fakes.TestIdentityv3):
+    domain = sdk_fakes.generate_fake_resource(_domain.Domain)
 
     columns = (
         'description',
@@ -652,22 +790,19 @@ class TestGroupShow(TestGroup):
 
     def setUp(self):
         super().setUp()
-        self.group = identity_fakes.FakeGroup.create_one_group(
-            attrs={'domain_id': self.domain.id}
+        self.group = sdk_fakes.generate_fake_resource(
+            _group.Group, description=None, domain_id=None
         )
-        self.data = (
-            self.group.description,
-            self.group.domain_id,
-            self.group.id,
-            self.group.name,
+        self.group_with_domain = sdk_fakes.generate_fake_resource(
+            _group.Group, name=self.group.name, domain_id=self.domain.id
         )
 
-        self.groups_mock.get.return_value = self.group
-        self.domains_mock.get.return_value = self.domain
+        self.identity_sdk_client.find_domain.return_value = self.domain
 
         self.cmd = group.ShowGroup(self.app, None)
 
     def test_group_show(self):
+        self.identity_sdk_client.find_group.return_value = self.group
         arglist = [
             self.group.id,
         ]
@@ -677,28 +812,44 @@ class TestGroupShow(TestGroup):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.groups_mock.get.assert_called_once_with(self.group.id)
+        self.identity_sdk_client.find_group.assert_called_once_with(
+            self.group.id, ignore_missing=False
+        )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        datalist = (
+            None,
+            None,
+            self.group.id,
+            self.group.name,
+        )
+        self.assertEqual(datalist, data)
 
     def test_group_show_with_domain(self):
-        get_mock_result = [exceptions.CommandError, self.group]
-        self.groups_mock.get = mock.Mock(side_effect=get_mock_result)
-
+        self.identity_sdk_client.find_group.return_value = (
+            self.group_with_domain
+        )
         arglist = [
             '--domain',
             self.domain.id,
-            self.group.id,
+            self.group_with_domain.name,
         ]
         verifylist = [
             ('domain', self.domain.id),
-            ('group', self.group.id),
+            ('group', self.group_with_domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.groups_mock.get.assert_any_call(
-            self.group.id, domain_id=self.domain.id
+        self.identity_sdk_client.find_group.assert_called_once_with(
+            self.group_with_domain.name,
+            domain_id=self.domain.id,
+            ignore_missing=False,
         )
         self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        datalist = (
+            self.group_with_domain.description,
+            self.domain.id,
+            self.group_with_domain.id,
+            self.group_with_domain.name,
+        )
+        self.assertEqual(datalist, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_mappings.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_mappings.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_mappings.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_mappings.py	2025-07-07 22:41:56.000000000 +0000
@@ -55,7 +55,7 @@ class TestMappingCreate(TestMapping):
         mocker = mock.Mock()
         mocker.return_value = identity_fakes.MAPPING_RULES
         with mock.patch(
-            "openstackclient.identity.v3.mapping." "CreateMapping._read_rules",
+            "openstackclient.identity.v3.mapping.CreateMapping._read_rules",
             mocker,
         ):
             columns, data = self.cmd.take_action(parsed_args)
@@ -170,7 +170,7 @@ class TestMappingSet(TestMapping):
         mocker = mock.Mock()
         mocker.return_value = identity_fakes.MAPPING_RULES_2
         with mock.patch(
-            "openstackclient.identity.v3.mapping." "SetMapping._read_rules",
+            "openstackclient.identity.v3.mapping.SetMapping._read_rules",
             mocker,
         ):
             result = self.cmd.take_action(parsed_args)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_project.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_project.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_project.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_project.py	2025-07-07 22:41:56.000000000 +0000
@@ -77,8 +77,7 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('parent', None),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('tags', []),
         ]
@@ -134,8 +133,7 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('description', 'new desc'),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', []),
@@ -172,8 +170,7 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', []),
@@ -210,8 +207,7 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', []),
@@ -243,8 +239,7 @@ class TestProjectCreate(TestProject):
             self.project.name,
         ]
         verifylist = [
-            ('enable', True),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', []),
@@ -279,8 +274,7 @@ class TestProjectCreate(TestProject):
             self.project.name,
         ]
         verifylist = [
-            ('enable', False),
-            ('disable', True),
+            ('enabled', False),
             ('name', self.project.name),
             ('parent', None),
         ]
@@ -317,7 +311,7 @@ class TestProjectCreate(TestProject):
             self.project.name,
         ]
         verifylist = [
-            ('property', {'fee': 'fi', 'fo': 'fum'}),
+            ('properties', {'fee': 'fi', 'fo': 'fum'}),
             ('name', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -354,11 +348,10 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('parent', None),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('tags', []),
-            ('property', {'is_domain': 'false'}),
+            ('properties', {'is_domain': 'false'}),
             ('name', self.project.name),
         ]
 
@@ -393,11 +386,10 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('parent', None),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('tags', []),
-            ('property', {'is_domain': 'true'}),
+            ('properties', {'is_domain': 'true'}),
             ('name', self.project.name),
         ]
 
@@ -432,11 +424,10 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('parent', None),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('tags', []),
-            ('property', {'is_domain': 'none'}),
+            ('properties', {'is_domain': 'none'}),
             ('name', self.project.name),
         ]
 
@@ -481,8 +472,7 @@ class TestProjectCreate(TestProject):
         verifylist = [
             ('domain', self.project.domain_id),
             ('parent', self.parent.name),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('tags', []),
         ]
@@ -544,8 +534,7 @@ class TestProjectCreate(TestProject):
         verifylist = [
             ('domain', self.project.domain_id),
             ('parent', 'invalid'),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -566,8 +555,7 @@ class TestProjectCreate(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', ['foo']),
@@ -602,8 +590,7 @@ class TestProjectCreate(TestProject):
         verifylist = [
             ('immutable', True),
             ('description', None),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', []),
@@ -638,10 +625,9 @@ class TestProjectCreate(TestProject):
             self.project.name,
         ]
         verifylist = [
-            ('no_immutable', True),
+            ('immutable', False),
             ('description', None),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', True),
             ('name', self.project.name),
             ('parent', None),
             ('tags', []),
@@ -941,6 +927,22 @@ class TestProjectList(TestProject):
         )
         self.assertEqual(datalist, tuple(data))
 
+    def test_project_list_with_option_enabled(self):
+        arglist = ['--enabled']
+        verifylist = [('is_enabled', True)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # In base command class Lister in cliff, abstract method take_action()
+        # returns a tuple containing the column names and an iterable
+        # containing the data to be listed.
+        columns, data = self.cmd.take_action(parsed_args)
+
+        kwargs = {'is_enabled': True}
+        self.projects_mock.list.assert_called_with(**kwargs)
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, tuple(data))
+
 
 class TestProjectSet(TestProject):
     domain = identity_fakes.FakeDomain.create_one_domain()
@@ -965,8 +967,7 @@ class TestProjectSet(TestProject):
         ]
         verifylist = [
             ('project', self.project.name),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', None),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -985,8 +986,7 @@ class TestProjectSet(TestProject):
         verifylist = [
             ('name', 'qwerty'),
             ('domain', self.project.domain_id),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', None),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1013,8 +1013,7 @@ class TestProjectSet(TestProject):
         verifylist = [
             ('domain', self.project.domain_id),
             ('description', 'new desc'),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', None),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1037,8 +1036,7 @@ class TestProjectSet(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('enable', True),
-            ('disable', False),
+            ('enabled', True),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1061,8 +1059,7 @@ class TestProjectSet(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('enable', False),
-            ('disable', True),
+            ('enabled', False),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1088,7 +1085,7 @@ class TestProjectSet(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('property', {'fee': 'fi', 'fo': 'fum'}),
+            ('properties', {'fee': 'fi', 'fo': 'fum'}),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1116,8 +1113,7 @@ class TestProjectSet(TestProject):
         verifylist = [
             ('name', 'qwerty'),
             ('domain', self.project.domain_id),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', None),
             ('project', self.project.name),
             ('tags', ['foo']),
         ]
@@ -1144,8 +1140,7 @@ class TestProjectSet(TestProject):
             self.project.name,
         ]
         verifylist = [
-            ('enable', False),
-            ('disable', False),
+            ('enabled', None),
             ('project', self.project.name),
             ('remove_tag', ['tag1', 'tag2']),
         ]
@@ -1167,8 +1162,7 @@ class TestProjectSet(TestProject):
         verifylist = [
             ('domain', self.project.domain_id),
             ('immutable', True),
-            ('enable', False),
-            ('disable', False),
+            ('enabled', None),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1191,9 +1185,8 @@ class TestProjectSet(TestProject):
         ]
         verifylist = [
             ('domain', self.project.domain_id),
-            ('no_immutable', True),
-            ('enable', False),
-            ('disable', False),
+            ('immutable', False),
+            ('enabled', None),
             ('project', self.project.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_role.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_role.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_role.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_role.py	2025-07-07 22:41:56.000000000 +0000
@@ -494,7 +494,6 @@ class TestRoleCreate(identity_fakes.Test
         # Set expected values
         kwargs = {
             'name': self.role.name,
-            'options': {},
         }
 
         self.identity_sdk_client.create_role.assert_called_with(**kwargs)
@@ -533,7 +532,6 @@ class TestRoleCreate(identity_fakes.Test
         kwargs = {
             'domain_id': self.domain.id,
             'name': self.role_with_domain.name,
-            'options': {},
         }
 
         self.identity_sdk_client.create_role.assert_called_with(**kwargs)
@@ -572,7 +570,6 @@ class TestRoleCreate(identity_fakes.Test
         kwargs = {
             'name': self.role_with_description.name,
             'description': self.role_with_description.description,
-            'options': {},
         }
 
         self.identity_sdk_client.create_role.assert_called_with(**kwargs)
@@ -629,7 +626,7 @@ class TestRoleCreate(identity_fakes.Test
             self.role.name,
         ]
         verifylist = [
-            ('no_immutable', True),
+            ('immutable', False),
             ('name', self.role.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1437,7 +1434,6 @@ class TestRoleSet(identity_fakes.TestIde
         kwargs = {
             'name': 'over',
             'role': self.role.id,
-            'options': {},
         }
         self.identity_sdk_client.update_role.assert_called_with(**kwargs)
         self.assertIsNone(result)
@@ -1472,7 +1468,6 @@ class TestRoleSet(identity_fakes.TestIde
             'name': 'over',
             'role': self.role_with_domain.id,
             'domain_id': self.domain2.id,
-            'options': {},
         }
         self.identity_sdk_client.update_role.assert_called_with(**kwargs)
         self.assertIsNone(result)
@@ -1501,7 +1496,6 @@ class TestRoleSet(identity_fakes.TestIde
             'name': 'over',
             'description': 'role description',
             'role': self.role_with_domain.id,
-            'options': {},
         }
         self.identity_sdk_client.update_role.assert_called_with(**kwargs)
         self.assertIsNone(result)
@@ -1544,7 +1538,7 @@ class TestRoleSet(identity_fakes.TestIde
         ]
         verifylist = [
             ('name', 'over'),
-            ('no_immutable', True),
+            ('immutable', False),
             ('role', self.role_with_domain.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_trust.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_trust.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_trust.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_trust.py	2025-07-07 22:41:56.000000000 +0000
@@ -70,12 +70,15 @@ class TestTrustCreate(identity_fakes.Tes
         # Set expected values
         kwargs = {
             'project_id': self.project.id,
-            'roles': [self.role.id],
+            'roles': [{'id': self.role.id}],
+            'impersonation': False,
         }
         # TrustManager.create(trustee_id, trustor_id, impersonation=,
         #   project=, role_names=, expires_at=)
         self.identity_sdk_client.create_trust.assert_called_with(
-            trustor_id=self.user.id, trustee_id=self.user.id, **kwargs
+            trustor_user_id=self.user.id,
+            trustee_user_id=self.user.id,
+            **kwargs,
         )
 
         collist = (
diff -pruN 7.4.0-3/openstackclient/tests/unit/identity/v3/test_user.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_user.py
--- 7.4.0-3/openstackclient/tests/unit/identity/v3/test_user.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/identity/v3/test_user.py	2025-07-07 22:41:56.000000000 +0000
@@ -44,6 +44,7 @@ class TestUserCreate(identity_fakes.Test
         'name',
         'description',
         'password_expires_at',
+        'options',
     )
 
     def setUp(self):
@@ -63,6 +64,7 @@ class TestUserCreate(identity_fakes.Test
             self.user.name,
             self.user.description,
             self.user.password_expires_at,
+            getattr(self.user, 'options', {}),
         )
 
         self.identity_sdk_client.find_domain.return_value = self.domain
@@ -163,6 +165,53 @@ class TestUserCreate(identity_fakes.Test
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
 
+    def test_user_create_password_prompt_no_warning(self):
+        arglist = [
+            '--password-prompt',
+            self.user.name,
+        ]
+        verifylist = [
+            ('password', None),
+            ('password_prompt', True),
+            ('enable', False),
+            ('disable', False),
+            ('name', self.user.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        import logging
+
+        # Mock the password prompt
+        mocker = mock.Mock()
+        mocker.return_value = 'abc123'
+
+        # Use assertLogs to verify no warnings are logged
+        logger = 'openstackclient.identity.v3.user'
+        with mock.patch("osc_lib.utils.get_password", mocker):
+            with self.assertLogs(logger, level='WARNING') as log_ctx:
+                logging.getLogger(logger).warning(
+                    "Dummy warning for test setup"
+                )
+                columns, data = self.cmd.take_action(parsed_args)
+
+                self.assertEqual(1, len(log_ctx.records))
+                self.assertIn(
+                    "Dummy warning for test setup", log_ctx.output[0]
+                )
+                self.assertNotIn(
+                    "No password was supplied", ''.join(log_ctx.output)
+                )
+
+        # Set expected values
+        kwargs = {
+            'name': self.user.name,
+            'is_enabled': True,
+            'password': 'abc123',
+        }
+        self.identity_sdk_client.create_user.assert_called_with(**kwargs)
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, data)
+
     def test_user_create_email(self):
         arglist = [
             '--email',
@@ -232,6 +281,7 @@ class TestUserCreate(identity_fakes.Test
             self.user.name,
             self.user.description,
             self.user.password_expires_at,
+            getattr(self.user, 'options', {}),
         )
         self.assertEqual(datalist, data)
 
@@ -279,6 +329,7 @@ class TestUserCreate(identity_fakes.Test
             self.user.name,
             self.user.description,
             self.user.password_expires_at,
+            getattr(self.user, 'options', {}),
         )
         self.assertEqual(datalist, data)
 
@@ -988,6 +1039,24 @@ class TestUserList(identity_fakes.TestId
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, tuple(data))
 
+    def test_user_list_with_option_enabled(self):
+        arglist = ['--enabled']
+        verifylist = [('is_enabled', True)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # In base command class Lister in cliff, abstract method take_action()
+        # returns a tuple containing the column names and an iterable
+        # containing the data to be listed.
+        columns, data = self.cmd.take_action(parsed_args)
+
+        kwargs = {'domain_id': None, 'is_enabled': True}
+        self.identity_sdk_client.users.assert_called_with(**kwargs)
+        self.identity_sdk_client.find_user.assert_not_called()
+        self.identity_sdk_client.group_users.assert_not_called()
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, tuple(data))
+
 
 class TestUserSet(identity_fakes.TestIdentityv3):
     project = sdk_fakes.generate_fake_resource(_project.Project)
@@ -1206,6 +1275,17 @@ class TestUserSet(identity_fakes.TestIde
         self.identity_sdk_client.update_user.assert_called_with(
             user=self.user, **kwargs
         )
+        self.identity_sdk_client.find_domain.assert_not_called()
+
+        # Set expected values
+        kwargs = {
+            'ignore_missing': False,
+            'domain_id': None,
+        }
+        self.identity_sdk_client.find_project.assert_called_once_with(
+            name_or_id=self.project.id, **kwargs
+        )
+
         self.assertIsNone(result)
 
     def test_user_set_project_domain(self):
@@ -1238,6 +1318,11 @@ class TestUserSet(identity_fakes.TestIde
         self.identity_sdk_client.update_user.assert_called_with(
             user=self.user, **kwargs
         )
+
+        self.identity_sdk_client.find_domain.assert_called_once_with(
+            name_or_id=self.project.domain_id, ignore_missing=False
+        )
+
         self.assertIsNone(result)
 
     def test_user_set_enable(self):
@@ -1670,11 +1755,14 @@ class TestUserSetPassword(identity_fakes
         # Mock getting user current password.
         with self._mock_get_password(current_pass):
             result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
+
+        conn = self.app.client_manager.sdk_connection
+        user_id = conn.config.get_auth().get_user_id(conn.identity)
 
         self.identity_sdk_client.update_user.assert_called_with(
-            current_password=current_pass, password=new_pass
+            user=user_id, current_password=current_pass, password=new_pass
         )
-        self.assertIsNone(result)
 
     def test_user_create_password_prompt(self):
         current_pass = 'old_pass'
@@ -1684,11 +1772,14 @@ class TestUserSetPassword(identity_fakes
         # Mock getting user current and new password.
         with self._mock_get_password(current_pass, new_pass):
             result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
+
+        conn = self.app.client_manager.sdk_connection
+        user_id = conn.config.get_auth().get_user_id(conn.identity)
 
         self.identity_sdk_client.update_user.assert_called_with(
-            current_password=current_pass, password=new_pass
+            user=user_id, current_password=current_pass, password=new_pass
         )
-        self.assertIsNone(result)
 
     def test_user_password_change_no_prompt(self):
         current_pass = 'old_pass'
@@ -1706,11 +1797,14 @@ class TestUserSetPassword(identity_fakes
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
+
+        conn = self.app.client_manager.sdk_connection
+        user_id = conn.config.get_auth().get_user_id(conn.identity)
 
         self.identity_sdk_client.update_user.assert_called_with(
-            current_password=current_pass, password=new_pass
+            user=user_id, current_password=current_pass, password=new_pass
         )
-        self.assertIsNone(result)
 
 
 class TestUserShow(identity_fakes.TestIdentityv3):
@@ -1763,6 +1857,7 @@ class TestUserShow(identity_fakes.TestId
             'name',
             'description',
             'password_expires_at',
+            'options',
         )
         self.assertEqual(collist, columns)
         datalist = (
@@ -1774,6 +1869,7 @@ class TestUserShow(identity_fakes.TestId
             self.user.name,
             self.user.description,
             self.user.password_expires_at,
+            getattr(self.user, 'options', {}),
         )
         self.assertEqual(datalist, data)
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/image/v1/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/image/v1/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/image/v1/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/image/v1/fakes.py	2025-07-07 22:41:56.000000000 +0000
@@ -20,7 +20,7 @@ from openstack.image.v1 import image
 
 from openstackclient.tests.unit import fakes
 from openstackclient.tests.unit import utils
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
+from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
 
 
 class FakeClientMixin:
@@ -35,7 +35,7 @@ class TestImagev1(FakeClientMixin, utils
     def setUp(self):
         super().setUp()
 
-        self.app.client_manager.volume = volume_fakes.FakeVolumev1Client(
+        self.app.client_manager.volume = volume_fakes.FakeVolumeClient(
             endpoint=fakes.AUTH_URL,
             token=fakes.AUTH_TOKEN,
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/image/v1/test_image.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/image/v1/test_image.py
--- 7.4.0-3/openstackclient/tests/unit/image/v1/test_image.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/image/v1/test_image.py	2025-07-07 22:41:56.000000000 +0000
@@ -54,9 +54,9 @@ class TestImageCreate(image_fakes.TestIm
     def setUp(self):
         super().setUp()
 
-        self.image_client.create_image = mock.Mock(return_value=self.new_image)
-        self.image_client.find_image = mock.Mock(return_value=self.new_image)
-        self.image_client.update_image = mock.Mock(return_image=self.new_image)
+        self.image_client.create_image.return_value = self.new_image
+        self.image_client.find_image.return_value = self.new_image
+        self.image_client.update_image.return_value = self.new_image
 
         # Get the command object to test
         self.cmd = image.CreateImage(self.app, None)
@@ -212,8 +212,8 @@ class TestImageDelete(image_fakes.TestIm
         super().setUp()
 
         # This is the return value for utils.find_resource()
-        self.image_client.find_image = mock.Mock(return_value=self._image)
-        self.image_client.delete_image = mock.Mock(return_value=None)
+        self.image_client.find_image.return_value = self._image
+        self.image_client.delete_image.return_value = None
 
         # Get the command object to test
         self.cmd = image.DeleteImage(self.app, None)
@@ -261,7 +261,6 @@ class TestImageList(image_fakes.TestImag
     def setUp(self):
         super().setUp()
 
-        self.image_client.images = mock.Mock()
         self.image_client.images.side_effect = [
             [self._image],
             [],
@@ -441,8 +440,8 @@ class TestImageSet(image_fakes.TestImage
         super().setUp()
 
         # This is the return value for utils.find_resource()
-        self.image_client.find_image = mock.Mock(return_value=self._image)
-        self.image_client.update_image = mock.Mock(return_value=self._image)
+        self.image_client.find_image.return_value = self._image
+        self.image_client.update_image.return_value = self._image
 
         # Get the command object to test
         self.cmd = image.SetImage(self.app, None)
@@ -712,7 +711,7 @@ class TestImageShow(image_fakes.TestImag
     def setUp(self):
         super().setUp()
 
-        self.image_client.find_image = mock.Mock(return_value=self._image)
+        self.image_client.find_image.return_value = self._image
 
         # Get the command object to test
         self.cmd = image.ShowImage(self.app, None)
diff -pruN 7.4.0-3/openstackclient/tests/unit/image/v2/test_image.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/image/v2/test_image.py
--- 7.4.0-3/openstackclient/tests/unit/image/v2/test_image.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/image/v2/test_image.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,8 +17,9 @@ import io
 import tempfile
 from unittest import mock
 
-from cinderclient import api_versions
+from openstack.block_storage.v2 import volume as _volume
 from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
 from osc_lib.cli import format_columns
 from osc_lib import exceptions
 
@@ -37,12 +38,6 @@ class TestImage(image_fakes.TestImagev2,
         self.project_mock.reset_mock()
         self.domain_mock = self.identity_client.domains
         self.domain_mock.reset_mock()
-        self.volumes_mock = self.volume_client.volumes
-        fake_body = {
-            'os-volume_upload_image': {'volume_type': {'name': 'fake_type'}}
-        }
-        self.volumes_mock.upload_to_image.return_value = (200, fake_body)
-        self.volumes_mock.reset_mock()
 
 
 class TestImageCreate(TestImage):
@@ -312,7 +307,6 @@ class TestImageCreate(TestImage):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        # ImageManager.create(name=, **)
         self.image_client.create_image.assert_called_with(
             name=self.new_image.name,
             allow_duplicates=True,
@@ -322,20 +316,19 @@ class TestImageCreate(TestImage):
         )
         self.image_client.get_image.assert_called_once_with(self.new_image)
 
-    @mock.patch('osc_lib.utils.find_resource')
     @mock.patch('openstackclient.image.v2.image.get_data_from_stdin')
-    def test_image_create_from_volume(self, mock_get_data_f, mock_get_vol):
-        fake_vol_id = 'fake-volume-id'
+    def test_image_create_from_volume(self, mock_get_data_f):
         mock_get_data_f.return_value = None
 
-        class FakeVolume:
-            id = fake_vol_id
-
-        mock_get_vol.return_value = FakeVolume()
+        volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = volume
+        self.volume_sdk_client.upload_volume_to_image.return_value = {
+            'volume_type': {'name': 'fake_type'}
+        }
 
         arglist = [
             '--volume',
-            fake_vol_id,
+            volume.id,
             self.new_image.name,
         ]
         verifylist = [
@@ -345,47 +338,60 @@ class TestImageCreate(TestImage):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.volumes_mock.upload_to_image.assert_called_with(
-            fake_vol_id, False, self.new_image.name, 'bare', 'raw'
+        self.volume_sdk_client.upload_volume_to_image.assert_called_once_with(
+            volume.id,
+            self.new_image.name,
+            force=False,
+            disk_format='raw',
+            container_format='bare',
+            visibility=None,
+            protected=None,
         )
 
-    @mock.patch('osc_lib.utils.find_resource')
     @mock.patch('openstackclient.image.v2.image.get_data_from_stdin')
-    def test_image_create_from_volume_fail(
-        self, mock_get_data_f, mock_get_vol
-    ):
-        fake_vol_id = 'fake-volume-id'
+    def test_image_create_from_volume_pre_v31(self, mock_get_data_f):
         mock_get_data_f.return_value = None
 
-        class FakeVolume:
-            id = fake_vol_id
-
-        mock_get_vol.return_value = FakeVolume()
+        volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = volume
+        self.volume_sdk_client.upload_volume_to_image.return_value = {
+            'volume_type': {'name': 'fake_type'}
+        }
 
-        arglist = ['--volume', fake_vol_id, self.new_image.name, '--public']
+        arglist = [
+            '--volume',
+            volume.id,
+            self.new_image.name,
+            '--public',
+        ]
         verifylist = [
             ('name', self.new_image.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.assertRaises(
+        exc = self.assertRaises(
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
+        self.assertIn('--os-volume-api-version 3.1 or greater ', str(exc))
 
-    @mock.patch('osc_lib.utils.find_resource')
     @mock.patch('openstackclient.image.v2.image.get_data_from_stdin')
-    def test_image_create_from_volume_v31(self, mock_get_data_f, mock_get_vol):
-        self.volume_client.api_version = api_versions.APIVersion('3.1')
+    def test_image_create_from_volume_v31(self, mock_get_data_f):
+        self.set_volume_api_version('3.1')
 
-        fake_vol_id = 'fake-volume-id'
         mock_get_data_f.return_value = None
 
-        class FakeVolume:
-            id = fake_vol_id
-
-        mock_get_vol.return_value = FakeVolume()
+        volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = volume
+        self.volume_sdk_client.upload_volume_to_image.return_value = {
+            'volume_type': {'name': 'fake_type'}
+        }
 
-        arglist = ['--volume', fake_vol_id, self.new_image.name, '--public']
+        arglist = [
+            '--volume',
+            volume.id,
+            self.new_image.name,
+            '--public',
+        ]
         verifylist = [
             ('name', self.new_image.name),
         ]
@@ -393,12 +399,12 @@ class TestImageCreate(TestImage):
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.volumes_mock.upload_to_image.assert_called_with(
-            fake_vol_id,
-            False,
+        self.volume_sdk_client.upload_volume_to_image.assert_called_once_with(
+            volume.id,
             self.new_image.name,
-            'bare',
-            'raw',
+            force=False,
+            disk_format='raw',
+            container_format='bare',
             visibility='public',
             protected=False,
         )
@@ -908,7 +914,7 @@ class TestImageList(TestImage):
         self.assertEqual(ret_limit, len(tuple(data)))
 
     def test_image_list_project_option(self):
-        self.image_client.find_image = mock.Mock(return_value=self._image)
+        self.image_client.find_image.return_value = self._image
         arglist = [
             '--project',
             'nova',
@@ -925,7 +931,7 @@ class TestImageList(TestImage):
 
     @mock.patch('osc_lib.utils.find_resource')
     def test_image_list_marker_option(self, fr_mock):
-        self.image_client.find_image = mock.Mock(return_value=self._image)
+        self.image_client.find_image.return_value = self._image
 
         arglist = [
             '--marker',
@@ -1715,7 +1721,7 @@ class TestImageShow(TestImage):
     def setUp(self):
         super().setUp()
 
-        self.image_client.find_image = mock.Mock(return_value=self._data)
+        self.image_client.find_image.return_value = self._data
 
         # Get the command object to test
         self.cmd = _image.ShowImage(self.app, None)
@@ -2033,6 +2039,36 @@ class TestImageImport(TestImage):
 
         self.image_client.import_image.assert_not_called()
 
+    def test_import_image__web_download_invalid_url(self):
+        arglist = [
+            self.image.name,
+            '--method',
+            'web-download',
+            '--uri',
+            'invalid:1234',
+        ]
+
+        verifylist = [
+            ('image', self.image.name),
+            ('import_method', 'web-download'),
+            ('uri', 'invalid:1234'),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+
+        self.assertIn(
+            "'invalid:1234' is not a valid url",
+            str(exc),
+        )
+
+        self.image_client.import_image.assert_not_called()
+
     def test_import_image__web_download_invalid_image_state(self):
         self.image.status = 'uploading'  # != 'queued'
         arglist = [
@@ -2092,6 +2128,38 @@ class TestImageImport(TestImage):
             all_stores_must_succeed=False,
         )
 
+    def test_import_image__copy_image_disallow_failure(self):
+        self.image.status = 'active'
+        arglist = [
+            self.image.name,
+            '--method',
+            'copy-image',
+            '--store',
+            'fast',
+            '--disallow-failure',
+        ]
+        verifylist = [
+            ('image', self.image.name),
+            ('import_method', 'copy-image'),
+            ('stores', ['fast']),
+            ('allow_failure', False),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+
+        self.image_client.import_image.assert_called_once_with(
+            self.image,
+            method='copy-image',
+            uri=None,
+            remote_region=None,
+            remote_image_id=None,
+            remote_service_interface=None,
+            stores=['fast'],
+            all_stores=None,
+            all_stores_must_succeed=True,
+        )
+
     def test_import_image__glance_download(self):
         arglist = [
             self.image.name,
diff -pruN 7.4.0-3/openstackclient/tests/unit/integ/cli/test_shell.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/integ/cli/test_shell.py
--- 7.4.0-3/openstackclient/tests/unit/integ/cli/test_shell.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/integ/cli/test_shell.py	2025-07-07 22:41:56.000000000 +0000
@@ -361,8 +361,7 @@ class TestIntegShellCliPrecedence(test_b
 
         _shell = shell.OpenStackShell()
         _shell.run(
-            "--os-username zarquon --os-password qaz "
-            "extension list".split(),
+            "--os-username zarquon --os-password qaz extension list".split(),
         )
 
         # Check general calls
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/test_common.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/test_common.py
--- 7.4.0-3/openstackclient/tests/unit/network/test_common.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/test_common.py	2025-07-07 22:41:56.000000000 +0000
@@ -132,8 +132,8 @@ class TestNetworkAndCompute(utils.TestCo
             return_value='take_action_network'
         )
 
-        self.app.client_manager.sdk_connection.compute = mock.Mock()
-        self.compute_client = self.app.client_manager.sdk_connection.compute
+        self.app.client_manager.compute = mock.Mock()
+        self.compute_client = self.app.client_manager.compute
         self.compute_client.compute_action = mock.Mock(
             return_value='take_action_compute'
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/fakes.py	2025-07-07 22:41:56.000000000 +0000
@@ -31,8 +31,24 @@ from openstack.network.v2 import network
 from openstack.network.v2 import network_ip_availability as _ip_availability
 from openstack.network.v2 import network_segment_range as _segment_range
 from openstack.network.v2 import port as _port
+from openstack.network.v2 import (
+    qos_bandwidth_limit_rule as _qos_bandwidth_limit_rule,
+)
+from openstack.network.v2 import (
+    qos_dscp_marking_rule as _qos_dscp_marking_rule,
+)
+from openstack.network.v2 import (
+    qos_minimum_bandwidth_rule as _qos_minimum_bandwidth_rule,
+)
+from openstack.network.v2 import (
+    qos_minimum_packet_rate_rule as _qos_minimum_packet_rate_rule,
+)
+from openstack.network.v2 import qos_policy as _qos_policy
+from openstack.network.v2 import qos_rule_type as _qos_rule_type
 from openstack.network.v2 import rbac_policy as network_rbac
+from openstack.network.v2 import router as _router
 from openstack.network.v2 import security_group as _security_group
+from openstack.network.v2 import security_group_rule as _security_group_rule
 from openstack.network.v2 import segment as _segment
 from openstack.network.v2 import service_profile as _service_profile
 from openstack.network.v2 import trunk as _trunk
@@ -118,485 +134,6 @@ def create_one_extension(attrs=None):
     return extension
 
 
-class FakeNetworkQosPolicy:
-    """Fake one or more QoS policies."""
-
-    @staticmethod
-    def create_one_qos_policy(attrs=None):
-        """Create a fake QoS policy.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object with name, id, etc.
-        """
-        attrs = attrs or {}
-        qos_id = attrs.get('id') or 'qos-policy-id-' + uuid.uuid4().hex
-        rule_attrs = {'qos_policy_id': qos_id}
-        rules = [FakeNetworkQosRule.create_one_qos_rule(rule_attrs)]
-
-        # Set default attributes.
-        qos_policy_attrs = {
-            'name': 'qos-policy-name-' + uuid.uuid4().hex,
-            'id': qos_id,
-            'is_default': False,
-            'project_id': 'project-id-' + uuid.uuid4().hex,
-            'shared': False,
-            'description': 'qos-policy-description-' + uuid.uuid4().hex,
-            'rules': rules,
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-
-        # Overwrite default attributes.
-        qos_policy_attrs.update(attrs)
-
-        qos_policy = fakes.FakeResource(
-            info=copy.deepcopy(qos_policy_attrs), loaded=True
-        )
-
-        # Set attributes with special mapping in OpenStack SDK.
-        qos_policy.is_shared = qos_policy_attrs['shared']
-
-        return qos_policy
-
-    @staticmethod
-    def create_qos_policies(attrs=None, count=2):
-        """Create multiple fake QoS policies.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of QoS policies to fake
-        :return:
-            A list of FakeResource objects faking the QoS policies
-        """
-        qos_policies = []
-        for i in range(0, count):
-            qos_policies.append(
-                FakeNetworkQosPolicy.create_one_qos_policy(attrs)
-            )
-
-        return qos_policies
-
-    @staticmethod
-    def get_qos_policies(qos_policies=None, count=2):
-        """Get an iterable MagicMock object with a list of faked QoS policies.
-
-        If qos policies list is provided, then initialize the Mock object
-        with the list. Otherwise create one.
-
-        :param List qos_policies:
-            A list of FakeResource objects faking qos policies
-        :param int count:
-            The number of QoS policies to fake
-        :return:
-            An iterable Mock object with side_effect set to a list of faked
-            QoS policies
-        """
-        if qos_policies is None:
-            qos_policies = FakeNetworkQosPolicy.create_qos_policies(count)
-        return mock.Mock(side_effect=qos_policies)
-
-
-class FakeNetworkSecGroup:
-    """Fake one security group."""
-
-    @staticmethod
-    def create_one_security_group(attrs=None):
-        """Create a fake security group.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object with name, id, etc.
-        """
-        attrs = attrs or {}
-        sg_id = attrs.get('id') or 'security-group-id-' + uuid.uuid4().hex
-
-        # Set default attributes.
-        security_group_attrs = {
-            'name': 'security-group-name-' + uuid.uuid4().hex,
-            'id': sg_id,
-            'project_id': 'project-id-' + uuid.uuid4().hex,
-            'description': 'security-group-description-' + uuid.uuid4().hex,
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-
-        security_group = fakes.FakeResource(
-            info=copy.deepcopy(security_group_attrs), loaded=True
-        )
-
-        return security_group
-
-
-class FakeNetworkQosRule:
-    """Fake one or more Network QoS rules."""
-
-    @staticmethod
-    def create_one_qos_rule(attrs=None):
-        """Create a fake Network QoS rule.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object with name, id, etc.
-        """
-        attrs = attrs or {}
-
-        # Set default attributes.
-        type = attrs.get('type') or choice(VALID_QOS_RULES)
-        qos_rule_attrs = {
-            'id': 'qos-rule-id-' + uuid.uuid4().hex,
-            'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
-            'project_id': 'project-id-' + uuid.uuid4().hex,
-            'type': type,
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-        if type == RULE_TYPE_BANDWIDTH_LIMIT:
-            qos_rule_attrs['max_kbps'] = randint(1, 10000)
-            qos_rule_attrs['max_burst_kbits'] = randint(1, 10000)
-            qos_rule_attrs['direction'] = 'egress'
-        elif type == RULE_TYPE_DSCP_MARKING:
-            qos_rule_attrs['dscp_mark'] = choice(VALID_DSCP_MARKS)
-        elif type == RULE_TYPE_MINIMUM_BANDWIDTH:
-            qos_rule_attrs['min_kbps'] = randint(1, 10000)
-            qos_rule_attrs['direction'] = 'egress'
-        elif type == RULE_TYPE_MINIMUM_PACKET_RATE:
-            qos_rule_attrs['min_kpps'] = randint(1, 10000)
-            qos_rule_attrs['direction'] = 'egress'
-
-        # Overwrite default attributes.
-        qos_rule_attrs.update(attrs)
-
-        qos_rule = fakes.FakeResource(
-            info=copy.deepcopy(qos_rule_attrs), loaded=True
-        )
-
-        return qos_rule
-
-    @staticmethod
-    def create_qos_rules(attrs=None, count=2):
-        """Create multiple fake Network QoS rules.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of Network QoS rule to fake
-        :return:
-            A list of FakeResource objects faking the Network QoS rules
-        """
-        qos_rules = []
-        for i in range(0, count):
-            qos_rules.append(FakeNetworkQosRule.create_one_qos_rule(attrs))
-        return qos_rules
-
-    @staticmethod
-    def get_qos_rules(qos_rules=None, count=2):
-        """Get a list of faked Network QoS rules.
-
-        If Network QoS rules list is provided, then initialize the Mock
-        object with the list. Otherwise create one.
-
-        :param List qos_rules:
-            A list of FakeResource objects faking Network QoS rules
-        :param int count:
-            The number of QoS minimum bandwidth rules to fake
-        :return:
-            An iterable Mock object with side_effect set to a list of faked
-            qos minimum bandwidth rules
-        """
-        if qos_rules is None:
-            qos_rules = FakeNetworkQosRule.create_qos_rules(count)
-        return mock.Mock(side_effect=qos_rules)
-
-
-class FakeNetworkQosRuleType:
-    """Fake one or more Network QoS rule types."""
-
-    @staticmethod
-    def create_one_qos_rule_type(attrs=None):
-        """Create a fake Network QoS rule type.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object with name, id, etc.
-        """
-        attrs = attrs or {}
-
-        # Set default attributes.
-        qos_rule_type_attrs = {
-            'type': 'rule-type-' + uuid.uuid4().hex,
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-
-        # Overwrite default attributes.
-        qos_rule_type_attrs.update(attrs)
-
-        return fakes.FakeResource(
-            info=copy.deepcopy(qos_rule_type_attrs), loaded=True
-        )
-
-    @staticmethod
-    def create_qos_rule_types(attrs=None, count=2):
-        """Create multiple fake Network QoS rule types.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of QoS rule types to fake
-        :return:
-            A list of FakeResource objects faking the QoS rule types
-        """
-        qos_rule_types = []
-        for i in range(0, count):
-            qos_rule_types.append(
-                FakeNetworkQosRuleType.create_one_qos_rule_type(attrs)
-            )
-
-        return qos_rule_types
-
-
-class FakeRouter:
-    """Fake one or more routers."""
-
-    @staticmethod
-    def create_one_router(attrs=None):
-        """Create a fake router.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object, with id, name, admin_state_up,
-            status, project_id
-        """
-        attrs = attrs or {}
-
-        # Set default attributes.
-        router_attrs = {
-            'id': 'router-id-' + uuid.uuid4().hex,
-            'name': 'router-name-' + uuid.uuid4().hex,
-            'status': 'ACTIVE',
-            'admin_state_up': True,
-            'description': 'router-description-' + uuid.uuid4().hex,
-            'distributed': False,
-            'ha': False,
-            'project_id': 'project-id-' + uuid.uuid4().hex,
-            'routes': [],
-            'external_gateway_info': {},
-            'availability_zone_hints': [],
-            'availability_zones': [],
-            'tags': [],
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-
-        # Overwrite default attributes.
-        router_attrs.update(attrs)
-
-        router = fakes.FakeResource(
-            info=copy.deepcopy(router_attrs), loaded=True
-        )
-
-        # Set attributes with special mapping in OpenStack SDK.
-        router.is_admin_state_up = router_attrs['admin_state_up']
-        router.is_distributed = router_attrs['distributed']
-        router.is_ha = router_attrs['ha']
-
-        return router
-
-    @staticmethod
-    def create_routers(attrs=None, count=2):
-        """Create multiple fake routers.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of routers to fake
-        :return:
-            A list of FakeResource objects faking the routers
-        """
-        routers = []
-        for i in range(0, count):
-            routers.append(FakeRouter.create_one_router(attrs))
-
-        return routers
-
-    @staticmethod
-    def get_routers(routers=None, count=2):
-        """Get an iterable Mock object with a list of faked routers.
-
-        If routers list is provided, then initialize the Mock object with the
-        list. Otherwise create one.
-
-        :param List routers:
-            A list of FakeResource objects faking routers
-        :param int count:
-            The number of routers to fake
-        :return:
-            An iterable Mock object with side_effect set to a list of faked
-            routers
-        """
-        if routers is None:
-            routers = FakeRouter.create_routers(count)
-        return mock.Mock(side_effect=routers)
-
-
-class FakeSecurityGroup:
-    """Fake one or more security groups."""
-
-    @staticmethod
-    def create_one_security_group(attrs=None):
-        """Create a fake security group.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object, with id, name, etc.
-        """
-        attrs = attrs or {}
-
-        # Set default attributes.
-        security_group_attrs = {
-            'id': 'security-group-id-' + uuid.uuid4().hex,
-            'name': 'security-group-name-' + uuid.uuid4().hex,
-            'description': 'security-group-description-' + uuid.uuid4().hex,
-            'stateful': True,
-            'project_id': 'project-id-' + uuid.uuid4().hex,
-            'security_group_rules': [],
-            'tags': [],
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-
-        # Overwrite default attributes.
-        security_group_attrs.update(attrs)
-
-        security_group = fakes.FakeResource(
-            info=copy.deepcopy(security_group_attrs), loaded=True
-        )
-
-        return security_group
-
-    @staticmethod
-    def create_security_groups(attrs=None, count=2):
-        """Create multiple fake security groups.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of security groups to fake
-        :return:
-            A list of FakeResource objects faking the security groups
-        """
-        security_groups = []
-        for i in range(0, count):
-            security_groups.append(
-                FakeSecurityGroup.create_one_security_group(attrs)
-            )
-
-        return security_groups
-
-    @staticmethod
-    def get_security_groups(security_groups=None, count=2):
-        """Get an iterable Mock object with a list of faked security groups.
-
-        If security groups list is provided, then initialize the Mock object
-        with the list. Otherwise create one.
-
-        :param List security_groups:
-            A list of FakeResource objects faking security groups
-        :param int count:
-            The number of security groups to fake
-        :return:
-            An iterable Mock object with side_effect set to a list of faked
-            security groups
-        """
-        if security_groups is None:
-            security_groups = FakeSecurityGroup.create_security_groups(count)
-        return mock.Mock(side_effect=security_groups)
-
-
-class FakeSecurityGroupRule:
-    """Fake one or more security group rules."""
-
-    @staticmethod
-    def create_one_security_group_rule(attrs=None):
-        """Create a fake security group rule.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :return:
-            A FakeResource object, with id, etc.
-        """
-        attrs = attrs or {}
-
-        # Set default attributes.
-        security_group_rule_attrs = {
-            'description': 'security-group-rule-description-'
-            + uuid.uuid4().hex,
-            'direction': 'ingress',
-            'ether_type': 'IPv4',
-            'id': 'security-group-rule-id-' + uuid.uuid4().hex,
-            'port_range_max': None,
-            'port_range_min': None,
-            'protocol': None,
-            'remote_group_id': None,
-            'remote_address_group_id': None,
-            'remote_ip_prefix': '0.0.0.0/0',
-            'security_group_id': 'security-group-id-' + uuid.uuid4().hex,
-            'project_id': 'project-id-' + uuid.uuid4().hex,
-            'location': 'MUNCHMUNCHMUNCH',
-        }
-
-        # Overwrite default attributes.
-        security_group_rule_attrs.update(attrs)
-
-        security_group_rule = fakes.FakeResource(
-            info=copy.deepcopy(security_group_rule_attrs), loaded=True
-        )
-
-        return security_group_rule
-
-    @staticmethod
-    def create_security_group_rules(attrs=None, count=2):
-        """Create multiple fake security group rules.
-
-        :param Dictionary attrs:
-            A dictionary with all attributes
-        :param int count:
-            The number of security group rules to fake
-        :return:
-            A list of FakeResource objects faking the security group rules
-        """
-        security_group_rules = []
-        for i in range(0, count):
-            security_group_rules.append(
-                FakeSecurityGroupRule.create_one_security_group_rule(attrs)
-            )
-
-        return security_group_rules
-
-    @staticmethod
-    def get_security_group_rules(security_group_rules=None, count=2):
-        """Get an iterable Mock with a list of faked security group rules.
-
-        If security group rules list is provided, then initialize the Mock
-        object with the list. Otherwise create one.
-
-        :param List security_group_rules:
-            A list of FakeResource objects faking security group rules
-        :param int count:
-            The number of security group rules to fake
-        :return:
-            An iterable Mock object with side_effect set to a list of faked
-            security group rules
-        """
-        if security_group_rules is None:
-            security_group_rules = (
-                FakeSecurityGroupRule.create_security_group_rules(count)
-            )
-        return mock.Mock(side_effect=security_group_rules)
-
-
 class FakeSubnet:
     """Fake one or more subnets."""
 
@@ -1856,20 +1393,32 @@ def get_network_rbacs(rbac_policies=None
 
 
 def create_one_security_group(attrs=None):
-    """Create a security group."""
+    """Create a fake security group.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :return:
+        A SecurityGroup object, with id, name, etc.
+    """
     attrs = attrs or {}
 
+    # Set default attributes.
     security_group_attrs = {
-        'name': 'security-group-name-' + uuid.uuid4().hex,
         'id': 'security-group-id-' + uuid.uuid4().hex,
-        'project_id': 'project-id-' + uuid.uuid4().hex,
+        'name': 'security-group-name-' + uuid.uuid4().hex,
         'description': 'security-group-description-' + uuid.uuid4().hex,
+        'stateful': True,
+        'project_id': 'project-id-' + uuid.uuid4().hex,
+        'security_group_rules': [],
+        'tags': [],
         'location': 'MUNCHMUNCHMUNCH',
     }
 
+    # Overwrite default attributes.
     security_group_attrs.update(attrs)
 
     security_group = _security_group.SecurityGroup(**security_group_attrs)
+    security_group.tenant_id = None  # unset deprecated opts
 
     return security_group
 
@@ -1877,9 +1426,12 @@ def create_one_security_group(attrs=None
 def create_security_groups(attrs=None, count=2):
     """Create multiple fake security groups.
 
-    :param dict attrs: A dictionary with all attributes
-    :param int count: The number of security groups to fake
-    :return: A list of fake SecurityGroup objects
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :param int count:
+        The number of security groups to fake
+    :return:
+        A list of SecurityGroup objects faking the security groups
     """
     security_groups = []
     for i in range(0, count):
@@ -1888,6 +1440,99 @@ def create_security_groups(attrs=None, c
     return security_groups
 
 
+def get_security_groups(security_groups=None, count=2):
+    """Get an iterable Mock object with a list of faked security groups.
+
+    If security groups list is provided, then initialize the Mock object
+    with the list. Otherwise create one.
+
+    :param List security_groups:
+        A list of SecurityGroup objects faking security groups
+    :param int count:
+        The number of security groups to fake
+    :return:
+        An iterable Mock object with side_effect set to a list of faked
+        security groups
+    """
+    if security_groups is None:
+        security_groups = create_security_groups(count)
+    return mock.Mock(side_effect=security_groups)
+
+
+def create_one_security_group_rule(attrs=None):
+    """Create a fake security group rule.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :return:
+        A FakeResource object, with id, etc.
+    """
+    attrs = attrs or {}
+
+    # Set default attributes.
+    security_group_rule_attrs = {
+        'description': 'security-group-rule-description-' + uuid.uuid4().hex,
+        'direction': 'ingress',
+        'ether_type': 'IPv4',
+        'id': 'security-group-rule-id-' + uuid.uuid4().hex,
+        'port_range_max': None,
+        'port_range_min': None,
+        'protocol': None,
+        'remote_group_id': None,
+        'remote_address_group_id': None,
+        'remote_ip_prefix': '0.0.0.0/0',
+        'security_group_id': 'security-group-id-' + uuid.uuid4().hex,
+        'project_id': 'project-id-' + uuid.uuid4().hex,
+        'location': 'MUNCHMUNCHMUNCH',
+    }
+
+    # Overwrite default attributes.
+    security_group_rule_attrs.update(attrs)
+
+    security_group_rule = _security_group_rule.SecurityGroupRule(
+        **security_group_rule_attrs
+    )
+    security_group_rule.tenant_id = None  # unset deprecated opts
+
+    return security_group_rule
+
+
+def create_security_group_rules(attrs=None, count=2):
+    """Create multiple fake security group rules.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :param int count:
+        The number of security group rules to fake
+    :return:
+        A list of SecurityGroupRule objects faking the security group rules
+    """
+    security_group_rules = []
+    for i in range(0, count):
+        security_group_rules.append(create_one_security_group_rule(attrs))
+
+    return security_group_rules
+
+
+def get_security_group_rules(security_group_rules=None, count=2):
+    """Get an iterable Mock with a list of faked security group rules.
+
+    If security group rules list is provided, then initialize the Mock
+    object with the list. Otherwise create one.
+
+    :param List security_group_rules:
+        A list of SecurityGroupRule objects faking security group rules
+    :param int count:
+        The number of security group rules to fake
+    :return:
+        An iterable Mock object with side_effect set to a list of faked
+        security group rules
+    """
+    if security_group_rules is None:
+        security_group_rules = create_security_group_rules(count)
+    return mock.Mock(side_effect=security_group_rules)
+
+
 def create_one_service_profile(attrs=None):
     """Create service profile."""
     attrs = attrs or {}
@@ -1926,6 +1571,281 @@ def get_service_profile(flavor_profile=N
     return mock.Mock(side_effect=flavor_profile)
 
 
+def create_one_qos_policy(attrs=None):
+    """Create a fake QoS policy.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :return:
+        A QoSPolicy object with name, id, etc.
+    """
+    attrs = attrs or {}
+    qos_id = attrs.get('id') or 'qos-policy-id-' + uuid.uuid4().hex
+    rules = []
+
+    # Set default attributes.
+    qos_policy_attrs = {
+        'name': 'qos-policy-name-' + uuid.uuid4().hex,
+        'id': qos_id,
+        'is_default': False,
+        'project_id': 'project-id-' + uuid.uuid4().hex,
+        'shared': False,
+        'description': 'qos-policy-description-' + uuid.uuid4().hex,
+        'rules': rules,
+        'location': 'MUNCHMUNCHMUNCH',
+    }
+
+    # Overwrite default attributes.
+    qos_policy_attrs.update(attrs)
+
+    qos_policy = _qos_policy.QoSPolicy(**qos_policy_attrs)
+
+    return qos_policy
+
+
+def create_qos_policies(attrs=None, count=2):
+    """Create multiple fake QoS policies.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :param int count:
+        The number of QoS policies to fake
+    :return:
+        A list of QoSPolicy objects faking the QoS policies
+    """
+    qos_policies = []
+    for i in range(0, count):
+        qos_policies.append(create_one_qos_policy(attrs))
+
+    return qos_policies
+
+
+def get_qos_policies(qos_policies=None, count=2):
+    """Get an iterable MagicMock object with a list of faked QoS policies.
+
+    If qos policies list is provided, then initialize the Mock object
+    with the list. Otherwise create one.
+
+    :param List qos_policies:
+        A list of QoSPolicy objects faking qos policies
+    :param int count:
+        The number of QoS policies to fake
+    :return:
+        An iterable Mock object with side_effect set to a list of faked
+        QoS policies
+    """
+    if qos_policies is None:
+        qos_policies = create_qos_policies(count)
+    return mock.Mock(side_effect=qos_policies)
+
+
+def create_one_qos_rule(attrs=None):
+    """Create a fake Network QoS rule.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :return:
+        A QoSRule object with  id, type, etc.
+    """
+    attrs = attrs or {}
+
+    # Set default attributes.
+    type = attrs.get('type') or choice(VALID_QOS_RULES)
+    qos_rule_attrs = {
+        'id': 'qos-rule-id-' + uuid.uuid4().hex,
+        'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
+        'project_id': 'project-id-' + uuid.uuid4().hex,
+        'type': type,
+        'location': 'MUNCHMUNCHMUNCH',
+    }
+
+    if type == RULE_TYPE_BANDWIDTH_LIMIT:
+        qos_rule_attrs['max_kbps'] = randint(1, 10000)
+        qos_rule_attrs['max_burst_kbps'] = randint(1, 10000)
+        qos_rule_attrs['direction'] = 'egress'
+
+        qos_rule_attrs.update(attrs)
+        qos_rule = _qos_bandwidth_limit_rule.QoSBandwidthLimitRule(
+            **qos_rule_attrs
+        )
+
+    elif type == RULE_TYPE_DSCP_MARKING:
+        qos_rule_attrs['dscp_mark'] = choice(VALID_DSCP_MARKS)
+
+        qos_rule_attrs.update(attrs)
+        qos_rule = _qos_dscp_marking_rule.QoSDSCPMarkingRule(**qos_rule_attrs)
+
+    elif type == RULE_TYPE_MINIMUM_BANDWIDTH:
+        qos_rule_attrs['min_kbps'] = randint(1, 10000)
+        qos_rule_attrs['direction'] = 'egress'
+
+        qos_rule_attrs.update(attrs)
+
+        qos_rule = _qos_minimum_bandwidth_rule.QoSMinimumBandwidthRule(
+            **qos_rule_attrs
+        )
+    else:  # type == RULE_TYPE_MINIMUM_PACKET_RATE:
+        qos_rule_attrs['min_kpps'] = randint(1, 10000)
+        qos_rule_attrs['direction'] = 'egress'
+
+        qos_rule_attrs.update(attrs)
+
+        qos_rule = _qos_minimum_packet_rate_rule.QoSMinimumPacketRateRule(
+            **qos_rule_attrs
+        )
+
+    return qos_rule
+
+
+def create_qos_rules(attrs=None, count=2):
+    """Create multiple fake Network QoS rules.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :param int count:
+        The number of Network QoS rule to fake
+    :return:
+        A list of QoS Rules objects faking the Network QoS rules
+    """
+    qos_rules = []
+    for i in range(0, count):
+        qos_rules.append(create_one_qos_rule(attrs))
+    return qos_rules
+
+
+def get_qos_rules(qos_rules=None, count=2):
+    """Get a list of faked Network QoS rules.
+
+    If Network QoS rules list is provided, then initialize the Mock
+    object with the list. Otherwise create one.
+
+    :param List qos_rules:
+        A list of FakeResource objects faking Network QoS rules
+    :param int count:
+        The number of QoS minimum bandwidth rules to fake
+    :return:
+        An iterable Mock object with side_effect set to a list of faked
+        qos minimum bandwidth rules
+    """
+    if qos_rules is None:
+        qos_rules = create_qos_rules(count)
+    return mock.Mock(side_effect=qos_rules)
+
+
+def create_one_qos_rule_type(attrs=None):
+    """Create a fake Network QoS rule type.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :return:
+        A QoSRuleType object with name, id, etc.
+    """
+    attrs = attrs or {}
+
+    # Set default attributes.
+    qos_rule_type_attrs = {
+        'type': 'rule-type-' + uuid.uuid4().hex,
+        'location': 'MUNCHMUNCHMUNCH',
+    }
+
+    # Overwrite default attributes.
+    qos_rule_type_attrs.update(attrs)
+    qos_rule_type = _qos_rule_type.QoSRuleType(**qos_rule_type_attrs)
+
+    return qos_rule_type
+
+
+def create_qos_rule_types(attrs=None, count=2):
+    """Create multiple fake Network QoS rule types.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :param int count:
+        The number of QoS rule types to fake
+    :return:
+        A list of QoSRuleType objects faking the QoS rule types
+    """
+    qos_rule_types = []
+    for i in range(0, count):
+        qos_rule_types.append(create_one_qos_rule_type(attrs))
+
+    return qos_rule_types
+
+
+def create_one_router(attrs=None):
+    """Create a fake router.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :return:
+        A Router object, with id, name, admin_state_up,
+        status, project_id
+    """
+    attrs = attrs or {}
+
+    # Set default attributes.
+    router_attrs = {
+        'id': 'router-id-' + uuid.uuid4().hex,
+        'name': 'router-name-' + uuid.uuid4().hex,
+        'status': 'ACTIVE',
+        'is_admin_state_up': True,
+        'description': 'router-description-' + uuid.uuid4().hex,
+        'distributed': False,
+        'ha': False,
+        'project_id': 'project-id-' + uuid.uuid4().hex,
+        'routes': [],
+        'external_gateway_info': {},
+        'availability_zone_hints': [],
+        'availability_zones': [],
+        'tags': [],
+        'location': 'MUNCHMUNCHMUNCH',
+    }
+
+    # Overwrite default attributes.
+    router_attrs.update(attrs)
+
+    router = _router.Router(**router_attrs)
+    router.tenant_id = None  # unset deprecated opts
+
+    return router
+
+
+def create_routers(attrs=None, count=2):
+    """Create multiple fake routers.
+
+    :param Dictionary attrs:
+        A dictionary with all attributes
+    :param int count:
+        The number of routers to fake
+    :return:
+        A list of Router objects faking the routers
+    """
+    routers = []
+    for i in range(0, count):
+        routers.append(create_one_router(attrs))
+
+    return routers
+
+
+def get_routers(routers=None, count=2):
+    """Get an iterable Mock object with a list of faked routers.
+
+    If routers list is provided, then initialize the Mock object with the
+    list. Otherwise create one.
+
+    :param List routers:
+        A list of Router objects faking routers
+    :param int count:
+        The number of routers to fake
+    :return:
+        An iterable Mock object with side_effect set to a list of faked
+        routers
+    """
+    if routers is None:
+        routers = create_routers(count)
+    return mock.Mock(side_effect=routers)
+
+
 def create_one_local_ip(attrs=None):
     """Create a fake local ip.
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_floating_ip_compute.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_floating_ip_compute.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_floating_ip_compute.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_floating_ip_compute.py	2025-07-07 22:41:56.000000000 +0000
@@ -73,7 +73,7 @@ class TestCreateFloatingIPCompute(comput
         columns, data = self.cmd.take_action(parsed_args)
 
         fip_mock.assert_called_once_with(
-            self.compute_sdk_client, self._floating_ip['pool']
+            self.compute_client, self._floating_ip['pool']
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
@@ -103,7 +103,7 @@ class TestDeleteFloatingIPCompute(comput
         result = self.cmd.take_action(parsed_args)
 
         fip_mock.assert_called_once_with(
-            self.compute_sdk_client, self._floating_ips[0]['id']
+            self.compute_client, self._floating_ips[0]['id']
         )
         self.assertIsNone(result)
 
@@ -122,12 +122,8 @@ class TestDeleteFloatingIPCompute(comput
 
         fip_mock.assert_has_calls(
             [
-                mock.call(
-                    self.compute_sdk_client, self._floating_ips[0]['id']
-                ),
-                mock.call(
-                    self.compute_sdk_client, self._floating_ips[1]['id']
-                ),
+                mock.call(self.compute_client, self._floating_ips[0]['id']),
+                mock.call(self.compute_client, self._floating_ips[1]['id']),
             ]
         )
         self.assertIsNone(result)
@@ -157,11 +153,9 @@ class TestDeleteFloatingIPCompute(comput
             self.assertEqual('1 of 2 floating_ips failed to delete.', str(e))
 
         fip_mock.assert_any_call(
-            self.compute_sdk_client, self._floating_ips[0]['id']
-        )
-        fip_mock.assert_any_call(
-            self.compute_sdk_client, 'unexist_floating_ip'
+            self.compute_client, self._floating_ips[0]['id']
         )
+        fip_mock.assert_any_call(self.compute_client, 'unexist_floating_ip')
 
 
 @mock.patch.object(compute_v2, 'list_floating_ips')
@@ -203,7 +197,7 @@ class TestListFloatingIPCompute(compute_
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        fip_mock.assert_called_once_with(self.compute_sdk_client)
+        fip_mock.assert_called_once_with(self.compute_client)
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
 
@@ -248,7 +242,7 @@ class TestShowFloatingIPCompute(compute_
         columns, data = self.cmd.take_action(parsed_args)
 
         fip_mock.assert_called_once_with(
-            self.compute_sdk_client, self._floating_ip['id']
+            self.compute_client, self._floating_ip['id']
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_floating_ip_network.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_floating_ip_network.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_floating_ip_network.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_floating_ip_network.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,6 +14,9 @@
 from unittest import mock
 from unittest.mock import call
 
+from openstack.network.v2 import floating_ip as _floating_ip
+from openstack.test import fakes as sdk_fakes
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
 
 from openstackclient.network.v2 import floating_ip as fip
@@ -231,10 +234,8 @@ class TestCreateFloatingIPNetwork(TestFl
         self.assertEqual(self.data, data)
 
     def test_create_floating_ip_with_qos(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
-        self.network_client.find_qos_policy = mock.Mock(
-            return_value=qos_policy
-        )
+        qos_policy = network_fakes.create_one_qos_policy()
+        self.network_client.find_qos_policy.return_value = qos_policy
         arglist = [
             '--qos-policy',
             qos_policy.id,
@@ -413,7 +414,7 @@ class TestListFloatingIPNetwork(TestFloa
             'id': 'fake_port_id',
         }
     )
-    fake_router = network_fakes.FakeRouter.create_one_router(
+    fake_router = network_fakes.create_one_router(
         {
             'id': 'fake_router_id',
         }
@@ -498,7 +499,7 @@ class TestListFloatingIPNetwork(TestFloa
             'fake_network_id',
         ]
         verifylist = [
-            ('network', 'fake_network_id'),
+            ('networks', ['fake_network_id']),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -506,7 +507,7 @@ class TestListFloatingIPNetwork(TestFloa
 
         self.network_client.ips.assert_called_once_with(
             **{
-                'floating_network_id': 'fake_network_id',
+                'floating_network_id': ['fake_network_id'],
             }
         )
         self.assertEqual(self.columns, columns)
@@ -518,7 +519,7 @@ class TestListFloatingIPNetwork(TestFloa
             'fake_port_id',
         ]
         verifylist = [
-            ('port', 'fake_port_id'),
+            ('ports', ['fake_port_id']),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -526,7 +527,7 @@ class TestListFloatingIPNetwork(TestFloa
 
         self.network_client.ips.assert_called_once_with(
             **{
-                'port_id': 'fake_port_id',
+                'port_id': ['fake_port_id'],
             }
         )
         self.assertEqual(self.columns, columns)
@@ -659,7 +660,7 @@ class TestListFloatingIPNetwork(TestFloa
             '--long',
         ]
         verifylist = [
-            ('router', 'fake_router_id'),
+            ('routers', ['fake_router_id']),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -667,7 +668,7 @@ class TestListFloatingIPNetwork(TestFloa
 
         self.network_client.ips.assert_called_once_with(
             **{
-                'router_id': 'fake_router_id',
+                'router_id': ['fake_router_id'],
             }
         )
         self.assertEqual(self.columns_long, columns)
@@ -706,46 +707,57 @@ class TestListFloatingIPNetwork(TestFloa
 
 
 class TestShowFloatingIPNetwork(TestFloatingIPNetwork):
-    # The floating ip to display.
-    floating_ip = network_fakes.FakeFloatingIP.create_one_floating_ip()
-
-    columns = (
-        'description',
-        'dns_domain',
-        'dns_name',
-        'fixed_ip_address',
-        'floating_ip_address',
-        'floating_network_id',
-        'id',
-        'port_id',
-        'project_id',
-        'qos_policy_id',
-        'router_id',
-        'status',
-        'tags',
-    )
-
-    data = (
-        floating_ip.description,
-        floating_ip.dns_domain,
-        floating_ip.dns_name,
-        floating_ip.fixed_ip_address,
-        floating_ip.floating_ip_address,
-        floating_ip.floating_network_id,
-        floating_ip.id,
-        floating_ip.port_id,
-        floating_ip.project_id,
-        floating_ip.qos_policy_id,
-        floating_ip.router_id,
-        floating_ip.status,
-        floating_ip.tags,
-    )
-
     def setUp(self):
         super().setUp()
 
+        self.floating_ip = sdk_fakes.generate_fake_resource(
+            _floating_ip.FloatingIP
+        )
         self.network_client.find_ip = mock.Mock(return_value=self.floating_ip)
 
+        self.columns = (
+            'created_at',
+            'description',
+            'dns_domain',
+            'dns_name',
+            'fixed_ip_address',
+            'floating_ip_address',
+            'floating_network_id',
+            'id',
+            'name',
+            'port_details',
+            'port_id',
+            'project_id',
+            'qos_policy_id',
+            'revision_number',
+            'router_id',
+            'status',
+            'subnet_id',
+            'tags',
+            'updated_at',
+        )
+        self.data = (
+            self.floating_ip.created_at,
+            self.floating_ip.description,
+            self.floating_ip.dns_domain,
+            self.floating_ip.dns_name,
+            self.floating_ip.fixed_ip_address,
+            self.floating_ip.floating_ip_address,
+            self.floating_ip.floating_network_id,
+            self.floating_ip.id,
+            self.floating_ip.name,
+            format_columns.DictColumn(self.floating_ip.port_details),
+            self.floating_ip.port_id,
+            self.floating_ip.project_id,
+            self.floating_ip.qos_policy_id,
+            self.floating_ip.revision_number,
+            self.floating_ip.router_id,
+            self.floating_ip.status,
+            self.floating_ip.subnet_id,
+            self.floating_ip.tags,
+            self.floating_ip.updated_at,
+        )
+
         # Get the command object to test
         self.cmd = fip.ShowFloatingIP(self.app, None)
 
@@ -879,10 +891,8 @@ class TestSetFloatingIP(TestFloatingIPNe
         )
 
     def test_qos_policy_option(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
-        self.network_client.find_qos_policy = mock.Mock(
-            return_value=qos_policy
-        )
+        qos_policy = network_fakes.create_one_qos_policy()
+        self.network_client.find_qos_policy.return_value = qos_policy
         arglist = [
             "--qos-policy",
             qos_policy.id,
@@ -908,10 +918,8 @@ class TestSetFloatingIP(TestFloatingIPNe
         )
 
     def test_port_and_qos_policy_option(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
-        self.network_client.find_qos_policy = mock.Mock(
-            return_value=qos_policy
-        )
+        qos_policy = network_fakes.create_one_qos_policy()
+        self.network_client.find_qos_policy.return_value = qos_policy
         arglist = [
             "--qos-policy",
             qos_policy.id,
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py	2025-07-07 22:41:56.000000000 +0000
@@ -44,6 +44,6 @@ class TestListFloatingIPPoolCompute(comp
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        fipp_mock.assert_called_once_with(self.compute_sdk_client)
+        fipp_mock.assert_called_once_with(self.compute_client)
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py	2025-07-07 22:41:56.000000000 +0000
@@ -24,8 +24,8 @@ class TestConntrackHelper(network_fakes.
     def setUp(self):
         super().setUp()
 
-        self.router = network_fakes.FakeRouter.create_one_router()
-        self.network_client.find_router = mock.Mock(return_value=self.router)
+        self.router = network_fakes.create_one_router()
+        self.network_client.find_router.return_value = self.router
 
 
 class TestCreateL3ConntrackHelper(TestConntrackHelper):
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_ndp_proxy.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_ndp_proxy.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_ndp_proxy.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_ndp_proxy.py	2025-07-07 22:41:56.000000000 +0000
@@ -30,9 +30,7 @@ class TestNDPProxy(network_fakes.TestNet
         # Get a shortcut to the DomainManager Mock
         self.domains_mock = self.identity_client.domains
 
-        self.router = network_fakes.FakeRouter.create_one_router(
-            {'id': 'fake-router-id'}
-        )
+        self.router = network_fakes.create_one_router({'id': 'fake-router-id'})
         self.network_client.find_router = mock.Mock(return_value=self.router)
         self.port = network_fakes.create_one_port()
         self.network_client.find_port = mock.Mock(return_value=self.port)
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network.py	2025-07-07 22:41:56.000000000 +0000
@@ -47,7 +47,7 @@ class TestCreateNetworkIdentityV3(TestNe
             'availability_zone_hints': ["nova"],
         }
     )
-    qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy(
+    qos_policy = network_fakes.create_one_qos_policy(
         attrs={'id': _network.qos_policy_id}
     )
 
@@ -622,7 +622,7 @@ class TestListNetwork(TestNetwork):
         self.network_client.networks = mock.Mock(return_value=self._network)
 
         self._agent = network_fakes.create_one_network_agent()
-        self.network_client.get_agent = mock.Mock(return_value=self._agent)
+        self.network_client.get_agent.return_value = self._agent
 
         self.network_client.dhcp_agent_hosting_networks = mock.Mock(
             return_value=self._network
@@ -967,7 +967,7 @@ class TestListNetwork(TestNetwork):
 class TestSetNetwork(TestNetwork):
     # The network to set.
     _network = network_fakes.create_one_network({'tags': ['green', 'red']})
-    qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy(
+    qos_policy = network_fakes.create_one_qos_policy(
         attrs={'id': _network.qos_policy_id}
     )
 
@@ -1266,7 +1266,7 @@ class TestShowNetwork(TestNetwork):
 class TestUnsetNetwork(TestNetwork):
     # The network to set.
     _network = network_fakes.create_one_network({'tags': ['green', 'red']})
-    qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy(
+    qos_policy = network_fakes.create_one_qos_policy(
         attrs={'id': _network.qos_policy_id}
     )
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_agent.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_agent.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_agent.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_agent.py	2025-07-07 22:41:56.000000000 +0000
@@ -70,7 +70,7 @@ class TestAddNetworkToAgent(TestNetworkA
 
 
 class TestAddRouterAgent(TestNetworkAgent):
-    _router = network_fakes.FakeRouter.create_one_router()
+    _router = network_fakes.create_one_router()
     _agent = network_fakes.create_one_network_agent()
 
     def setUp(self):
@@ -219,30 +219,24 @@ class TestListNetworkAgent(TestNetworkAg
 
     def setUp(self):
         super().setUp()
-        self.network_client.agents = mock.Mock(
-            return_value=self.network_agents
+
+        self.network_client.agents.return_value = self.network_agents
+        self.network_client.routers_hosting_l3_agents.return_value = (
+            self.network_agents
         )
 
         _testagent = network_fakes.create_one_network_agent()
-        self.network_client.get_agent = mock.Mock(return_value=_testagent)
+        self.network_client.get_agent.return_value = _testagent
+        self.network_client.get_agent.return_value = _testagent
 
         self._testnetwork = network_fakes.create_one_network()
-        self.network_client.find_network = mock.Mock(
-            return_value=self._testnetwork
-        )
-        self.network_client.network_hosting_dhcp_agents = mock.Mock(
-            return_value=self.network_agents
+        self.network_client.find_network.return_value = self._testnetwork
+        self.network_client.network_hosting_dhcp_agents.return_value = (
+            self.network_agents
         )
 
-        self.network_client.get_agent = mock.Mock(return_value=_testagent)
-
-        self._testrouter = network_fakes.FakeRouter.create_one_router()
-        self.network_client.find_router = mock.Mock(
-            return_value=self._testrouter
-        )
-        self.network_client.routers_hosting_l3_agents = mock.Mock(
-            return_value=self.network_agents
-        )
+        self._testrouter = network_fakes.create_one_router()
+        self.network_client.find_router.return_value = self._testrouter
 
         # Get the command object to test
         self.cmd = network_agent.ListNetworkAgent(self.app, None)
@@ -323,15 +317,11 @@ class TestListNetworkAgent(TestNetworkAg
         ]
         verifylist = [('router', self._testrouter.id), ('long', False)]
 
-        attrs = {
-            self._testrouter,
-        }
-
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
         self.network_client.routers_hosting_l3_agents.assert_called_once_with(
-            *attrs
+            self._testrouter
         )
 
         self.assertEqual(self.columns, columns)
@@ -345,15 +335,11 @@ class TestListNetworkAgent(TestNetworkAg
         ]
         verifylist = [('router', self._testrouter.id), ('long', True)]
 
-        attrs = {
-            self._testrouter,
-        }
-
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         columns, data = self.cmd.take_action(parsed_args)
 
         self.network_client.routers_hosting_l3_agents.assert_called_once_with(
-            *attrs
+            self._testrouter
         )
 
         # Add a column 'HA State' and corresponding data.
@@ -422,7 +408,7 @@ class TestRemoveNetworkFromAgent(TestNet
 
 
 class TestRemoveRouterAgent(TestNetworkAgent):
-    _router = network_fakes.FakeRouter.create_one_router()
+    _router = network_fakes.create_one_router()
     _agent = network_fakes.create_one_network_agent()
 
     def setUp(self):
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_compute.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_compute.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_compute.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_compute.py	2025-07-07 22:41:56.000000000 +0000
@@ -148,7 +148,7 @@ class TestCreateNetworkCompute(compute_f
         columns, data = self.cmd.take_action(parsed_args)
 
         net_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             subnet=self._network['cidr'],
             name=self._network['label'],
         )
@@ -182,7 +182,7 @@ class TestDeleteNetworkCompute(compute_f
         result = self.cmd.take_action(parsed_args)
 
         delete_net_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             self._networks[0]['id'],
         )
         self.assertIsNone(result)
@@ -203,8 +203,8 @@ class TestDeleteNetworkCompute(compute_f
 
         delete_net_mock.assert_has_calls(
             [
-                mock.call(self.compute_sdk_client, self._networks[0]['id']),
-                mock.call(self.compute_sdk_client, self._networks[1]['id']),
+                mock.call(self.compute_client, self._networks[0]['id']),
+                mock.call(self.compute_client, self._networks[1]['id']),
             ]
         )
         self.assertIsNone(result)
@@ -238,15 +238,15 @@ class TestDeleteNetworkCompute(compute_f
 
         find_net_mock.assert_has_calls(
             [
-                mock.call(self.compute_sdk_client, self._networks[0]['id']),
-                mock.call(self.compute_sdk_client, 'xxxx-yyyy-zzzz'),
-                mock.call(self.compute_sdk_client, self._networks[1]['id']),
+                mock.call(self.compute_client, self._networks[0]['id']),
+                mock.call(self.compute_client, 'xxxx-yyyy-zzzz'),
+                mock.call(self.compute_client, self._networks[1]['id']),
             ]
         )
         delete_net_mock.assert_has_calls(
             [
-                mock.call(self.compute_sdk_client, self._networks[0]['id']),
-                mock.call(self.compute_sdk_client, self._networks[1]['id']),
+                mock.call(self.compute_client, self._networks[0]['id']),
+                mock.call(self.compute_client, self._networks[1]['id']),
             ]
         )
 
@@ -286,7 +286,7 @@ class TestListNetworkCompute(compute_fak
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        net_mock.assert_called_once_with(self.compute_sdk_client)
+        net_mock.assert_called_once_with(self.compute_client)
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
 
@@ -398,7 +398,7 @@ class TestShowNetworkCompute(compute_fak
         columns, data = self.cmd.take_action(parsed_args)
 
         net_mock.assert_called_once_with(
-            self.compute_sdk_client, self._network['label']
+            self.compute_client, self._network['label']
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_qos_policy.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_qos_policy.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_qos_policy.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_qos_policy.py	2025-07-07 22:41:56.000000000 +0000
@@ -35,11 +35,10 @@ class TestCreateNetworkQosPolicy(TestQos
     project = identity_fakes_v3.FakeProject.create_one_project()
 
     # The new qos policy created.
-    new_qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy(
-        attrs={
-            'project_id': project.id,
-        }
+    new_qos_policy = network_fakes.create_one_qos_policy(
+        attrs={'project_id': project.id}
     )
+
     columns = (
         'description',
         'id',
@@ -48,6 +47,7 @@ class TestCreateNetworkQosPolicy(TestQos
         'project_id',
         'rules',
         'shared',
+        'tags',
     )
 
     data = (
@@ -57,7 +57,8 @@ class TestCreateNetworkQosPolicy(TestQos
         new_qos_policy.name,
         new_qos_policy.project_id,
         new_qos_policy.rules,
-        new_qos_policy.shared,
+        new_qos_policy.is_shared,
+        new_qos_policy.tags,
     )
 
     def setUp(self):
@@ -158,17 +159,13 @@ class TestCreateNetworkQosPolicy(TestQos
 
 class TestDeleteNetworkQosPolicy(TestQosPolicy):
     # The address scope to delete.
-    _qos_policies = network_fakes.FakeNetworkQosPolicy.create_qos_policies(
-        count=2
-    )
+    _qos_policies = network_fakes.create_qos_policies(count=2)
 
     def setUp(self):
         super().setUp()
         self.network_client.delete_qos_policy = mock.Mock(return_value=None)
-        self.network_client.find_qos_policy = (
-            network_fakes.FakeNetworkQosPolicy.get_qos_policies(
-                qos_policies=self._qos_policies
-            )
+        self.network_client.find_qos_policy = network_fakes.get_qos_policies(
+            qos_policies=self._qos_policies
         )
 
         # Get the command object to test
@@ -245,9 +242,7 @@ class TestDeleteNetworkQosPolicy(TestQos
 
 class TestListNetworkQosPolicy(TestQosPolicy):
     # The QoS policies to list up.
-    qos_policies = network_fakes.FakeNetworkQosPolicy.create_qos_policies(
-        count=3
-    )
+    qos_policies = network_fakes.create_qos_policies(count=3)
     columns = (
         'ID',
         'Name',
@@ -261,7 +256,7 @@ class TestListNetworkQosPolicy(TestQosPo
             (
                 qos_policy.id,
                 qos_policy.name,
-                qos_policy.shared,
+                qos_policy.is_shared,
                 qos_policy.is_default,
                 qos_policy.project_id,
             )
@@ -345,7 +340,7 @@ class TestListNetworkQosPolicy(TestQosPo
 
 class TestSetNetworkQosPolicy(TestQosPolicy):
     # The QoS policy to set.
-    _qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+    _qos_policy = network_fakes.create_one_qos_policy()
 
     def setUp(self):
         super().setUp()
@@ -428,7 +423,7 @@ class TestSetNetworkQosPolicy(TestQosPol
 
 class TestShowNetworkQosPolicy(TestQosPolicy):
     # The QoS policy to show.
-    _qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+    _qos_policy = network_fakes.create_one_qos_policy()
     columns = (
         'description',
         'id',
@@ -437,6 +432,7 @@ class TestShowNetworkQosPolicy(TestQosPo
         'project_id',
         'rules',
         'shared',
+        'tags',
     )
     data = (
         _qos_policy.description,
@@ -445,7 +441,8 @@ class TestShowNetworkQosPolicy(TestQosPo
         _qos_policy.name,
         _qos_policy.project_id,
         network_qos_policy.RulesColumn(_qos_policy.rules),
-        _qos_policy.shared,
+        _qos_policy.is_shared,
+        _qos_policy.tags,
     )
 
     def setUp(self):
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_qos_rule.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_qos_rule.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_qos_rule.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_qos_rule.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,6 +14,7 @@
 #    under the License.
 
 from unittest import mock
+import uuid
 
 from osc_lib import exceptions
 
@@ -54,9 +55,7 @@ DSCP_VALID_MARKS = [
 class TestNetworkQosRule(network_fakes.TestNetworkV2):
     def setUp(self):
         super().setUp()
-        self.qos_policy = (
-            network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
-        )
+        self.qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=self.qos_policy
         )
@@ -72,15 +71,12 @@ class TestCreateNetworkQosRuleMinimumBan
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_BANDWIDTH,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.columns = (
             'direction',
             'id',
             'min_kbps',
             'project_id',
-            'qos_policy_id',
             'type',
         )
 
@@ -89,7 +85,6 @@ class TestCreateNetworkQosRuleMinimumBan
             self.new_rule.id,
             self.new_rule.min_kbps,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
         self.network_client.create_qos_minimum_bandwidth_rule = mock.Mock(
@@ -179,15 +174,12 @@ class TestCreateNetworkQosRuleMinimumPac
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_PACKET_RATE,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.columns = (
             'direction',
             'id',
             'min_kpps',
             'project_id',
-            'qos_policy_id',
             'type',
         )
 
@@ -196,7 +188,6 @@ class TestCreateNetworkQosRuleMinimumPac
             self.new_rule.id,
             self.new_rule.min_kpps,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
         self.network_client.create_qos_minimum_packet_rate_rule = mock.Mock(
@@ -286,14 +277,11 @@ class TestCreateNetworkQosRuleDSCPMarkin
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_DSCP_MARKING,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.columns = (
             'dscp_mark',
             'id',
             'project_id',
-            'qos_policy_id',
             'type',
         )
 
@@ -301,7 +289,6 @@ class TestCreateNetworkQosRuleDSCPMarkin
             self.new_rule.dscp_mark,
             self.new_rule.id,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
         self.network_client.create_qos_dscp_marking_rule = mock.Mock(
@@ -384,26 +371,22 @@ class TestCreateNetworkQosRuleBandwidtLi
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_BANDWIDTH_LIMIT,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.columns = (
             'direction',
             'id',
-            'max_burst_kbits',
+            'max_burst_kbps',
             'max_kbps',
             'project_id',
-            'qos_policy_id',
             'type',
         )
 
         self.data = (
             self.new_rule.direction,
             self.new_rule.id,
-            self.new_rule.max_burst_kbits,
+            self.new_rule.max_burst_kbps,
             self.new_rule.max_kbps,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
         self.network_client.create_qos_bandwidth_limit_rule = mock.Mock(
@@ -443,20 +426,19 @@ class TestCreateNetworkQosRuleBandwidtLi
             ('qos_policy', self.new_rule.qos_policy_id),
         ]
 
-        rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+        rule = network_fakes.create_one_qos_rule(
             {
                 'qos_policy_id': self.qos_policy.id,
                 'type': RULE_TYPE_BANDWIDTH_LIMIT,
             }
         )
-        rule.max_burst_kbits = 0
+        rule.max_burst_kbps = 0
         expected_data = (
             rule.direction,
             rule.id,
-            rule.max_burst_kbits,
+            rule.max_burst_kbps,
             rule.max_kbps,
             rule.project_id,
-            rule.qos_policy_id,
             rule.type,
         )
 
@@ -485,7 +467,7 @@ class TestCreateNetworkQosRuleBandwidtLi
             '--max-kbps',
             str(self.new_rule.max_kbps),
             '--max-burst-kbits',
-            str(self.new_rule.max_burst_kbits),
+            str(self.new_rule.max_burst_kbps),
             '--egress',
             self.new_rule.qos_policy_id,
         ]
@@ -493,7 +475,7 @@ class TestCreateNetworkQosRuleBandwidtLi
         verifylist = [
             ('type', RULE_TYPE_BANDWIDTH_LIMIT),
             ('max_kbps', self.new_rule.max_kbps),
-            ('max_burst_kbits', self.new_rule.max_burst_kbits),
+            ('max_burst_kbits', self.new_rule.max_burst_kbps),
             ('egress', True),
             ('qos_policy', self.new_rule.qos_policy_id),
         ]
@@ -505,7 +487,7 @@ class TestCreateNetworkQosRuleBandwidtLi
             self.qos_policy.id,
             **{
                 'max_kbps': self.new_rule.max_kbps,
-                'max_burst_kbps': self.new_rule.max_burst_kbits,
+                'max_burst_kbps': self.new_rule.max_burst_kbps,
                 'direction': self.new_rule.direction,
             },
         )
@@ -545,17 +527,13 @@ class TestDeleteNetworkQosRuleMinimumBan
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_BANDWIDTH,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.delete_qos_minimum_bandwidth_rule = mock.Mock(
             return_value=None
         )
         self.network_client.find_qos_minimum_bandwidth_rule = (
-            network_fakes.FakeNetworkQosRule.get_qos_rules(
-                qos_rules=self.new_rule
-            )
+            network_fakes.get_qos_rules(qos_rules=self.new_rule)
         )
 
         # Get the command object to test
@@ -612,17 +590,13 @@ class TestDeleteNetworkQosRuleMinimumPac
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_PACKET_RATE,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.delete_qos_minimum_packet_rate_rule = mock.Mock(
             return_value=None
         )
         self.network_client.find_qos_minimum_packet_rate_rule = (
-            network_fakes.FakeNetworkQosRule.get_qos_rules(
-                qos_rules=self.new_rule
-            )
+            network_fakes.get_qos_rules(qos_rules=self.new_rule)
         )
 
         # Get the command object to test
@@ -679,17 +653,13 @@ class TestDeleteNetworkQosRuleDSCPMarkin
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_DSCP_MARKING,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.delete_qos_dscp_marking_rule = mock.Mock(
             return_value=None
         )
         self.network_client.find_qos_dscp_marking_rule = (
-            network_fakes.FakeNetworkQosRule.get_qos_rules(
-                qos_rules=self.new_rule
-            )
+            network_fakes.get_qos_rules(qos_rules=self.new_rule)
         )
 
         # Get the command object to test
@@ -746,17 +716,13 @@ class TestDeleteNetworkQosRuleBandwidthL
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_BANDWIDTH_LIMIT,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.delete_qos_bandwidth_limit_rule = mock.Mock(
             return_value=None
         )
         self.network_client.find_qos_bandwidth_limit_rule = (
-            network_fakes.FakeNetworkQosRule.get_qos_rules(
-                qos_rules=self.new_rule
-            )
+            network_fakes.get_qos_rules(qos_rules=self.new_rule)
         )
 
         # Get the command object to test
@@ -813,9 +779,7 @@ class TestSetNetworkQosRuleMinimumBandwi
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_BANDWIDTH,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs=attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.update_qos_minimum_bandwidth_rule = mock.Mock(
             return_value=None
@@ -917,9 +881,7 @@ class TestSetNetworkQosRuleMinimumPacket
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_PACKET_RATE,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs=attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.update_qos_minimum_packet_rate_rule = mock.Mock(
             return_value=None
@@ -1021,9 +983,7 @@ class TestSetNetworkQosRuleDSCPMarking(T
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_DSCP_MARKING,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs=attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.network_client.update_qos_dscp_marking_rule = mock.Mock(
             return_value=None
@@ -1124,21 +1084,14 @@ class TestSetNetworkQosRuleBandwidthLimi
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_BANDWIDTH_LIMIT,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs=attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
-        self.network_client.update_qos_bandwidth_limit_rule = mock.Mock(
-            return_value=None
-        )
-        self.network_client.find_qos_bandwidth_limit_rule = mock.Mock(
-            return_value=self.new_rule
-        )
-        self.network_client.find_qos_policy = mock.Mock(
-            return_value=self.qos_policy
+        self.network_client.update_qos_bandwidth_limit_rule.return_value = None
+        self.network_client.find_qos_bandwidth_limit_rule.return_value = (
+            self.new_rule
         )
+        self.network_client.find_qos_policy.return_value = self.qos_policy
 
-        # Get the command object to test
         self.cmd = network_qos_rule.SetNetworkQosRule(self.app, None)
 
     def test_set_nothing(self):
@@ -1203,23 +1156,23 @@ class TestSetNetworkQosRuleBandwidthLimi
         self._set_max_burst_kbits(max_burst_kbits=0)
 
     def _reset_max_burst_kbits(self, max_burst_kbits):
-        self.new_rule.max_burst_kbits = max_burst_kbits
+        self.new_rule.max_burst_kbps = max_burst_kbits
 
     def _set_max_burst_kbits(self, max_burst_kbits=None):
         if max_burst_kbits:
             self.addCleanup(
-                self._reset_max_burst_kbits, self.new_rule.max_burst_kbits
+                self._reset_max_burst_kbits, self.new_rule.max_burst_kbps
             )
-            self.new_rule.max_burst_kbits = max_burst_kbits
+            self.new_rule.max_burst_kbps = max_burst_kbits
 
         arglist = [
             '--max-burst-kbits',
-            str(self.new_rule.max_burst_kbits),
+            str(self.new_rule.max_burst_kbps),
             self.new_rule.qos_policy_id,
             self.new_rule.id,
         ]
         verifylist = [
-            ('max_burst_kbits', self.new_rule.max_burst_kbits),
+            ('max_burst_kbits', self.new_rule.max_burst_kbps),
             ('qos_policy', self.new_rule.qos_policy_id),
             ('id', self.new_rule.id),
         ]
@@ -1228,7 +1181,7 @@ class TestSetNetworkQosRuleBandwidthLimi
         result = self.cmd.take_action(parsed_args)
 
         attrs = {
-            'max_burst_kbps': self.new_rule.max_burst_kbits,
+            'max_burst_kbps': self.new_rule.max_burst_kbps,
         }
         self.network_client.update_qos_bandwidth_limit_rule.assert_called_with(
             self.new_rule, self.qos_policy.id, **attrs
@@ -1297,43 +1250,36 @@ class TestSetNetworkQosRuleBandwidthLimi
 class TestListNetworkQosRule(TestNetworkQosRule):
     def setUp(self):
         super().setUp()
-        attrs = {
-            'qos_policy_id': self.qos_policy.id,
-            'type': RULE_TYPE_MINIMUM_BANDWIDTH,
-        }
-        self.new_rule_min_bw = (
-            network_fakes.FakeNetworkQosRule.create_one_qos_rule(attrs=attrs)
-        )
-        attrs['type'] = RULE_TYPE_MINIMUM_PACKET_RATE
-        self.new_rule_min_pps = (
-            network_fakes.FakeNetworkQosRule.create_one_qos_rule(attrs=attrs)
-        )
-        attrs['type'] = RULE_TYPE_DSCP_MARKING
-        self.new_rule_dscp_mark = (
-            network_fakes.FakeNetworkQosRule.create_one_qos_rule(attrs=attrs)
-        )
-        attrs['type'] = RULE_TYPE_BANDWIDTH_LIMIT
-        self.new_rule_max_bw = (
-            network_fakes.FakeNetworkQosRule.create_one_qos_rule(attrs=attrs)
-        )
         self.qos_policy.rules = [
-            self.new_rule_min_bw,
-            self.new_rule_min_pps,
-            self.new_rule_dscp_mark,
-            self.new_rule_max_bw,
+            {
+                'max_kbps': 1024,
+                'max_burst_kbps': 1024,
+                'direction': 'egress',
+                'id': 'qos-rule-id-' + uuid.uuid4().hex,
+                'qos_policy_id': self.qos_policy.id,
+                'type': 'bandwidth_limit',
+            },
+            {
+                'dscp_mark': 0,
+                'id': 'qos-rule-id-' + uuid.uuid4().hex,
+                'qos_policy_id': self.qos_policy.id,
+                'type': 'dscp_marking',
+            },
+            {
+                'min_kbps': 1024,
+                'direction': 'egress',
+                'id': 'qos-rule-id-' + uuid.uuid4().hex,
+                'qos_policy_id': self.qos_policy.id,
+                'type': 'minimum_bandwidth',
+            },
+            {
+                'min_kpps': 2800,
+                'direction': 'egress',
+                'id': 'qos-rule-id-' + uuid.uuid4().hex,
+                'qos_policy_id': self.qos_policy.id,
+                'type': 'minimum_packet_rate',
+            },
         ]
-        self.network_client.find_qos_minimum_bandwidth_rule = mock.Mock(
-            return_value=self.new_rule_min_bw
-        )
-        self.network_client.find_qos_minimum_packet_rate_rule = mock.Mock(
-            return_value=self.new_rule_min_pps
-        )
-        self.network_client.find_qos_dscp_marking_rule = mock.Mock(
-            return_value=self.new_rule_dscp_mark
-        )
-        self.network_client.find_qos_bandwidth_limit_rule = mock.Mock(
-            return_value=self.new_rule_max_bw
-        )
         self.columns = (
             'ID',
             'QoS Policy ID',
@@ -1349,20 +1295,17 @@ class TestListNetworkQosRule(TestNetwork
         for index in range(len(self.qos_policy.rules)):
             self.data.append(
                 (
-                    self.qos_policy.rules[index].id,
-                    self.qos_policy.rules[index].qos_policy_id,
-                    self.qos_policy.rules[index].type,
-                    getattr(self.qos_policy.rules[index], 'max_kbps', ''),
-                    getattr(
-                        self.qos_policy.rules[index], 'max_burst_kbps', ''
-                    ),
-                    getattr(self.qos_policy.rules[index], 'min_kbps', ''),
-                    getattr(self.qos_policy.rules[index], 'min_kpps', ''),
-                    getattr(self.qos_policy.rules[index], 'dscp_mark', ''),
-                    getattr(self.qos_policy.rules[index], 'direction', ''),
+                    self.qos_policy.rules[index]['id'],
+                    self.qos_policy.id,
+                    self.qos_policy.rules[index]['type'],
+                    self.qos_policy.rules[index].get('max_kbps', ''),
+                    self.qos_policy.rules[index].get('max_burst_kbps', ''),
+                    self.qos_policy.rules[index].get('min_kbps', ''),
+                    self.qos_policy.rules[index].get('min_kpps', ''),
+                    self.qos_policy.rules[index].get('dscp_mark', ''),
+                    self.qos_policy.rules[index].get('direction', ''),
                 )
             )
-        # Get the command object to test
         self.cmd = network_qos_rule.ListNetworkQosRule(self.app, None)
 
     def test_qos_rule_list(self):
@@ -1391,16 +1334,13 @@ class TestShowNetworkQosRuleMinimumBandw
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_BANDWIDTH,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.columns = (
             'direction',
             'id',
             'min_kbps',
             'project_id',
-            'qos_policy_id',
             'type',
         )
         self.data = (
@@ -1408,7 +1348,6 @@ class TestShowNetworkQosRuleMinimumBandw
             self.new_rule.id,
             self.new_rule.min_kbps,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
 
@@ -1459,16 +1398,13 @@ class TestShowNetworkQosRuleMinimumPacke
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_MINIMUM_PACKET_RATE,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.columns = (
             'direction',
             'id',
             'min_kpps',
             'project_id',
-            'qos_policy_id',
             'type',
         )
         self.data = (
@@ -1476,7 +1412,6 @@ class TestShowNetworkQosRuleMinimumPacke
             self.new_rule.id,
             self.new_rule.min_kpps,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
 
@@ -1527,22 +1462,18 @@ class TestShowNetworkQosDSCPMarking(Test
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_DSCP_MARKING,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.columns = (
             'dscp_mark',
             'id',
             'project_id',
-            'qos_policy_id',
             'type',
         )
         self.data = (
             self.new_rule.dscp_mark,
             self.new_rule.id,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
 
@@ -1593,26 +1524,22 @@ class TestShowNetworkQosBandwidthLimit(T
             'qos_policy_id': self.qos_policy.id,
             'type': RULE_TYPE_BANDWIDTH_LIMIT,
         }
-        self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
-            attrs
-        )
+        self.new_rule = network_fakes.create_one_qos_rule(attrs)
         self.qos_policy.rules = [self.new_rule]
         self.columns = (
             'direction',
             'id',
-            'max_burst_kbits',
+            'max_burst_kbps',
             'max_kbps',
             'project_id',
-            'qos_policy_id',
             'type',
         )
         self.data = (
             self.new_rule.direction,
             self.new_rule.id,
-            self.new_rule.max_burst_kbits,
+            self.new_rule.max_burst_kbps,
             self.new_rule.max_kbps,
             self.new_rule.project_id,
-            self.new_rule.qos_policy_id,
             self.new_rule.type,
         )
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,9 +28,8 @@ class TestNetworkQosRuleType(network_fak
 class TestShowNetworkQosRuleType(TestNetworkQosRuleType):
     attrs = {'drivers': [{'name': 'driver 1', 'supported_parameters': []}]}
     # The QoS policies to show.
-    qos_rule_type = (
-        network_fakes.FakeNetworkQosRuleType.create_one_qos_rule_type(attrs)
-    )
+    qos_rule_type = network_fakes.create_one_qos_rule_type(attrs)
+    columns = ('drivers', 'rule_type_name')
     columns = ('drivers', 'rule_type_name')
     data = [qos_rule_type.drivers, qos_rule_type.type]
 
@@ -76,9 +75,8 @@ class TestShowNetworkQosRuleType(TestNet
 
 class TestListNetworkQosRuleType(TestNetworkQosRuleType):
     # The QoS policies to list up.
-    qos_rule_types = (
-        network_fakes.FakeNetworkQosRuleType.create_qos_rule_types(count=3)
-    )
+    qos_rule_types = network_fakes.create_qos_rule_types(count=3)
+
     columns = ('Type',)
     data = []
     for qos_rule_type in qos_rule_types:
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_rbac.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_rbac.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_rbac.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_rbac.py	2025-07-07 22:41:56.000000000 +0000
@@ -34,8 +34,8 @@ class TestNetworkRBAC(network_fakes.Test
 @ddt.ddt
 class TestCreateNetworkRBAC(TestNetworkRBAC):
     network_object = network_fakes.create_one_network()
-    qos_object = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
-    sg_object = network_fakes.FakeNetworkSecGroup.create_one_security_group()
+    qos_object = network_fakes.create_one_qos_policy()
+    sg_object = network_fakes.create_one_security_group()
     as_object = network_fakes.create_one_address_scope()
     snp_object = network_fakes.FakeSubnetPool.create_one_subnet_pool()
     ag_object = network_fakes.create_one_address_group()
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_trunk.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_trunk.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_network_trunk.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_network_trunk.py	2025-07-07 22:41:56.000000000 +0000
@@ -263,7 +263,7 @@ class TestCreateNetworkTrunk(TestNetwork
             '--parent-port',
             self.new_trunk.port_id,
             '--subport',
-            'segmentation-type={seg_type},' 'segmentation-id={seg_id}'.format(
+            'segmentation-type={seg_type},segmentation-id={seg_id}'.format(
                 seg_id=subport['segmentation_id'],
                 seg_type=subport['segmentation_type'],
             ),
@@ -727,7 +727,7 @@ class TestSetNetworkTrunk(TestNetworkTru
         subport = self._trunk['sub_ports'][0]
         arglist = [
             '--subport',
-            'segmentation-type={seg_type},' 'segmentation-id={seg_id}'.format(
+            'segmentation-type={seg_type},segmentation-id={seg_id}'.format(
                 seg_id=subport['segmentation_id'],
                 seg_type=subport['segmentation_type'],
             ),
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_port.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_port.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_port.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_port.py	2025-07-07 22:41:56.000000000 +0000
@@ -320,7 +320,7 @@ class TestCreatePort(TestPort):
         self.assertCountEqual(self.data, data)
 
     def test_create_with_security_group(self):
-        secgroup = network_fakes.FakeSecurityGroup.create_one_security_group()
+        secgroup = network_fakes.create_one_security_group()
         self.network_client.find_security_group = mock.Mock(
             return_value=secgroup
         )
@@ -391,8 +391,8 @@ class TestCreatePort(TestPort):
         self.assertCountEqual(self.data, data)
 
     def test_create_with_security_groups(self):
-        sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group()
-        sg_2 = network_fakes.FakeSecurityGroup.create_one_security_group()
+        sg_1 = network_fakes.create_one_security_group()
+        sg_2 = network_fakes.create_one_security_group()
         self.network_client.find_security_group = mock.Mock(
             side_effect=[sg_1, sg_2]
         )
@@ -582,7 +582,7 @@ class TestCreatePort(TestPort):
         self.assertCountEqual(self.data, data)
 
     def test_create_port_with_qos(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
@@ -807,8 +807,7 @@ class TestCreatePort(TestPort):
         extra_dhcp_options = [
             {
                 'opt_name': 'classless-static-route',
-                'opt_value': '169.254.169.254/32,22.2.0.2,'
-                '0.0.0.0/0,22.2.0.1',
+                'opt_value': '169.254.169.254/32,22.2.0.2,0.0.0.0/0,22.2.0.1',
                 'ip_version': '4',
             },
             {
@@ -826,7 +825,7 @@ class TestCreatePort(TestPort):
             '0.0.0.0/0,22.2.0.1,'
             'ip-version=4',
             '--extra-dhcp-option',
-            'name=dns-server,value=240C::6666,' 'ip-version=6',
+            'name=dns-server,value=240C::6666,ip-version=6',
             'test-port',
         ]
 
@@ -1326,7 +1325,7 @@ class TestListPort(compute_fakes.FakeCli
         super().setUp()
 
         self.network_client.ports = mock.Mock(return_value=self._ports)
-        fake_router = network_fakes.FakeRouter.create_one_router(
+        fake_router = network_fakes.create_one_router(
             {
                 'id': 'fake-router-id',
             }
@@ -1378,8 +1377,8 @@ class TestListPort(compute_fakes.FakeCli
         self.assertCountEqual(self.data, list(data))
 
     def test_port_list_with_server_option(self):
-        fake_server = compute_fakes.create_one_sdk_server()
-        self.compute_sdk_client.find_server.return_value = fake_server
+        fake_server = compute_fakes.create_one_server()
+        self.compute_client.find_server.return_value = fake_server
 
         arglist = [
             '--server',
@@ -1394,7 +1393,7 @@ class TestListPort(compute_fakes.FakeCli
         self.network_client.ports.assert_called_once_with(
             device_id=fake_server.id, fields=LIST_FIELDS_TO_RETRIEVE
         )
-        self.compute_sdk_client.find_server.aassert_called_once_with(
+        self.compute_client.find_server.aassert_called_once_with(
             mock.ANY, 'fake-server-name'
         )
         self.assertEqual(self.columns, columns)
@@ -2097,7 +2096,7 @@ class TestSetPort(TestPort):
         self.assertIsNone(result)
 
     def test_set_port_security_group(self):
-        sg = network_fakes.FakeSecurityGroup.create_one_security_group()
+        sg = network_fakes.create_one_security_group()
         self.network_client.find_security_group = mock.Mock(return_value=sg)
         arglist = [
             '--security-group',
@@ -2120,9 +2119,9 @@ class TestSetPort(TestPort):
         self.assertIsNone(result)
 
     def test_set_port_security_group_append(self):
-        sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group()
-        sg_2 = network_fakes.FakeSecurityGroup.create_one_security_group()
-        sg_3 = network_fakes.FakeSecurityGroup.create_one_security_group()
+        sg_1 = network_fakes.create_one_security_group()
+        sg_2 = network_fakes.create_one_security_group()
+        sg_3 = network_fakes.create_one_security_group()
         self.network_client.find_security_group = mock.Mock(
             side_effect=[sg_2, sg_3]
         )
@@ -2173,8 +2172,8 @@ class TestSetPort(TestPort):
         self.assertIsNone(result)
 
     def test_set_port_security_group_replace(self):
-        sg1 = network_fakes.FakeSecurityGroup.create_one_security_group()
-        sg2 = network_fakes.FakeSecurityGroup.create_one_security_group()
+        sg1 = network_fakes.create_one_security_group()
+        sg2 = network_fakes.create_one_security_group()
         _testport = network_fakes.create_one_port(
             {'security_group_ids': [sg1.id]}
         )
@@ -2372,7 +2371,7 @@ class TestSetPort(TestPort):
         )
 
     def test_set_port_with_qos(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
@@ -2822,8 +2821,8 @@ class TestUnsetPort(TestPort):
         )
 
     def test_unset_security_group(self):
-        _fake_sg1 = network_fakes.FakeSecurityGroup.create_one_security_group()
-        _fake_sg2 = network_fakes.FakeSecurityGroup.create_one_security_group()
+        _fake_sg1 = network_fakes.create_one_security_group()
+        _fake_sg2 = network_fakes.create_one_security_group()
         _fake_port = network_fakes.create_one_port(
             {'security_group_ids': [_fake_sg1.id, _fake_sg2.id]}
         )
@@ -2850,8 +2849,8 @@ class TestUnsetPort(TestPort):
         self.assertIsNone(result)
 
     def test_unset_port_security_group_not_existent(self):
-        _fake_sg1 = network_fakes.FakeSecurityGroup.create_one_security_group()
-        _fake_sg2 = network_fakes.FakeSecurityGroup.create_one_security_group()
+        _fake_sg1 = network_fakes.create_one_security_group()
+        _fake_sg2 = network_fakes.create_one_security_group()
         _fake_port = network_fakes.create_one_port(
             {'security_group_ids': [_fake_sg1.id]}
         )
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_router.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_router.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_router.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_router.py	2025-07-07 22:41:56.000000000 +0000
@@ -34,9 +34,7 @@ class TestAddPortToRouter(TestRouter):
     '''Add port to Router'''
 
     _port = network_fakes.create_one_port()
-    _router = network_fakes.FakeRouter.create_one_router(
-        attrs={'port': _port.id}
-    )
+    _router = network_fakes.create_one_router(attrs={'port': _port.id})
 
     def setUp(self):
         super().setUp()
@@ -84,9 +82,7 @@ class TestAddSubnetToRouter(TestRouter):
     '''Add subnet to Router'''
 
     _subnet = network_fakes.FakeSubnet.create_one_subnet()
-    _router = network_fakes.FakeRouter.create_one_router(
-        attrs={'subnet': _subnet.id}
-    )
+    _router = network_fakes.create_one_router(attrs={'subnet': _subnet.id})
 
     def setUp(self):
         super().setUp()
@@ -129,38 +125,48 @@ class TestAddSubnetToRouter(TestRouter):
 
 class TestCreateRouter(TestRouter):
     # The new router created.
-    new_router = network_fakes.FakeRouter.create_one_router()
+    new_router = network_fakes.create_one_router()
     _extensions = {'fake': network_fakes.create_one_extension()}
 
     columns = (
         'admin_state_up',
         'availability_zone_hints',
         'availability_zones',
+        'created_at',
         'description',
         'distributed',
+        'enable_ndp_proxy',
         'external_gateway_info',
+        'flavor_id',
         'ha',
         'id',
         'name',
         'project_id',
+        'revision_number',
         'routes',
         'status',
         'tags',
+        'updated_at',
     )
     data = (
-        router.AdminStateColumn(new_router.admin_state_up),
+        router.AdminStateColumn(new_router.is_admin_state_up),
         format_columns.ListColumn(new_router.availability_zone_hints),
         format_columns.ListColumn(new_router.availability_zones),
+        new_router.created_at,
         new_router.description,
-        new_router.distributed,
+        new_router.is_distributed,
+        new_router.enable_ndp_proxy,
         router.RouterInfoColumn(new_router.external_gateway_info),
-        new_router.ha,
+        new_router.flavor_id,
+        new_router.is_ha,
         new_router.id,
         new_router.name,
         new_router.project_id,
+        new_router.revision_number,
         router.RoutesColumn(new_router.routes),
         new_router.status,
         format_columns.ListColumn(new_router.tags),
+        new_router.updated_at,
     )
 
     def setUp(self):
@@ -552,17 +558,76 @@ class TestCreateRouter(TestRouter):
             parsed_args,
         )
 
+    def test_create_with_qos_policy(self):
+        _network = network_fakes.create_one_network()
+        self.network_client.find_network = mock.Mock(return_value=_network)
+        _qos_policy = network_fakes.create_one_qos_policy()
+        self.network_client.find_qos_policy = mock.Mock(
+            return_value=_qos_policy
+        )
+        arglist = [
+            self.new_router.name,
+            '--external-gateway',
+            _network.id,
+            '--qos-policy',
+            _qos_policy.id,
+        ]
+        verifylist = [
+            ('name', self.new_router.name),
+            ('enable', True),
+            ('distributed', False),
+            ('ha', False),
+            ('qos_policy', _qos_policy.id),
+            ('external_gateways', [_network.id]),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+        gw_info = {'network_id': _network.id, 'qos_policy_id': _qos_policy.id}
+        self.network_client.create_router.assert_called_once_with(
+            **{
+                'admin_state_up': True,
+                'name': self.new_router.name,
+                **{'external_gateway_info': gw_info},
+            }
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertCountEqual(self.data, data)
+
+    def test_create_with_qos_policy_no_external_gateway(self):
+        _qos_policy = network_fakes.create_one_qos_policy()
+        self.network_client.find_qos_policy = mock.Mock(
+            return_value=_qos_policy
+        )
+        arglist = [
+            self.new_router.name,
+            '--qos-policy',
+            _qos_policy.id,
+        ]
+        verifylist = [
+            ('name', self.new_router.name),
+            ('enable', True),
+            ('distributed', False),
+            ('ha', False),
+            ('qos_policy', _qos_policy.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+
 
 class TestDeleteRouter(TestRouter):
     # The routers to delete.
-    _routers = network_fakes.FakeRouter.create_routers(count=2)
+    _routers = network_fakes.create_routers(count=2)
 
     def setUp(self):
         super().setUp()
 
         self.network_client.delete_router = mock.Mock(return_value=None)
 
-        self.network_client.find_router = network_fakes.FakeRouter.get_routers(
+        self.network_client.find_router = network_fakes.get_routers(
             self._routers
         )
 
@@ -637,7 +702,7 @@ class TestDeleteRouter(TestRouter):
 
 class TestListRouter(TestRouter):
     # The routers going to be listed up.
-    routers = network_fakes.FakeRouter.create_routers(count=3)
+    routers = network_fakes.create_routers(count=3)
     extensions = network_fakes.create_one_extension()
 
     columns = (
@@ -668,10 +733,10 @@ class TestListRouter(TestRouter):
                 r.id,
                 r.name,
                 r.status,
-                router.AdminStateColumn(r.admin_state_up),
+                router.AdminStateColumn(r.is_admin_state_up),
                 r.project_id,
-                r.distributed,
-                r.ha,
+                r.is_distributed,
+                r.is_ha,
             )
         )
 
@@ -754,7 +819,7 @@ class TestListRouter(TestRouter):
         self.assertCountEqual(self.data, list(data))
 
     def test_router_list_no_ha_no_distributed(self):
-        _routers = network_fakes.FakeRouter.create_routers(
+        _routers = network_fakes.create_routers(
             {'ha': None, 'distributed': None}, count=3
         )
 
@@ -974,9 +1039,7 @@ class TestRemovePortFromRouter(TestRoute
     '''Remove port from a Router'''
 
     _port = network_fakes.create_one_port()
-    _router = network_fakes.FakeRouter.create_one_router(
-        attrs={'port': _port.id}
-    )
+    _router = network_fakes.create_one_router(attrs={'port': _port.id})
 
     def setUp(self):
         super().setUp()
@@ -1021,9 +1084,7 @@ class TestRemoveSubnetFromRouter(TestRou
     '''Remove subnet from Router'''
 
     _subnet = network_fakes.FakeSubnet.create_one_subnet()
-    _router = network_fakes.FakeRouter.create_one_router(
-        attrs={'subnet': _subnet.id}
-    )
+    _router = network_fakes.create_one_router(attrs={'subnet': _subnet.id})
 
     def setUp(self):
         super().setUp()
@@ -1064,7 +1125,7 @@ class TestRemoveSubnetFromRouter(TestRou
 
 
 class TestAddExtraRoutesToRouter(TestRouter):
-    _router = network_fakes.FakeRouter.create_one_router()
+    _router = network_fakes.create_one_router()
 
     def setUp(self):
         super().setUp()
@@ -1153,7 +1214,7 @@ class TestAddExtraRoutesToRouter(TestRou
 
 
 class TestRemoveExtraRoutesFromRouter(TestRouter):
-    _router = network_fakes.FakeRouter.create_one_router()
+    _router = network_fakes.create_one_router()
 
     def setUp(self):
         super().setUp()
@@ -1248,7 +1309,7 @@ class TestSetRouter(TestRouter):
     _subnet = network_fakes.FakeSubnet.create_one_subnet(
         attrs={'network_id': _network.id}
     )
-    _router = network_fakes.FakeRouter.create_one_router(
+    _router = network_fakes.create_one_router(
         attrs={'routes': [_default_route], 'tags': ['green', 'red']}
     )
     _extensions = {'fake': network_fakes.create_one_extension()}
@@ -1395,7 +1456,7 @@ class TestSetRouter(TestRouter):
         self.assertIsNone(result)
 
     def test_set_route_overwrite_route(self):
-        _testrouter = network_fakes.FakeRouter.create_one_router(
+        _testrouter = network_fakes.create_one_router(
             {'routes': [{"destination": "10.0.0.2", "nexthop": "1.1.1.1"}]}
         )
         self.network_client.find_router = mock.Mock(return_value=_testrouter)
@@ -1605,7 +1666,7 @@ class TestSetRouter(TestRouter):
         self._test_set_tags(with_tags=False)
 
     def test_set_gateway_ip_qos(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
@@ -1662,7 +1723,7 @@ class TestSetRouter(TestRouter):
         self.assertIsNone(result)
 
     def test_set_unset_gateway_ip_qos(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
@@ -1690,11 +1751,11 @@ class TestSetRouter(TestRouter):
         )
 
     def test_set_gateway_ip_qos_no_gateway(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
-        router = network_fakes.FakeRouter.create_one_router()
+        router = network_fakes.create_one_router()
         self.network_client.find_router = mock.Mock(return_value=router)
         arglist = [
             "--qos-policy",
@@ -1712,11 +1773,11 @@ class TestSetRouter(TestRouter):
         )
 
     def test_unset_gateway_ip_qos_no_gateway(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
-        router = network_fakes.FakeRouter.create_one_router()
+        router = network_fakes.create_one_router()
         self.network_client.find_router = mock.Mock(return_value=router)
         arglist = [
             "--no-qos-policy",
@@ -1734,7 +1795,7 @@ class TestSetRouter(TestRouter):
 
 class TestShowRouter(TestRouter):
     # The router to set.
-    _router = network_fakes.FakeRouter.create_one_router()
+    _router = network_fakes.create_one_router()
     _port = network_fakes.create_one_port(
         {'device_owner': 'network:router_interface', 'device_id': _router.id}
     )
@@ -1754,33 +1815,43 @@ class TestShowRouter(TestRouter):
         'admin_state_up',
         'availability_zone_hints',
         'availability_zones',
+        'created_at',
         'description',
         'distributed',
+        'enable_ndp_proxy',
         'external_gateway_info',
+        'flavor_id',
         'ha',
         'id',
         'interfaces_info',
         'name',
         'project_id',
+        'revision_number',
         'routes',
         'status',
         'tags',
+        'updated_at',
     )
     data = (
-        router.AdminStateColumn(_router.admin_state_up),
+        router.AdminStateColumn(_router.is_admin_state_up),
         format_columns.ListColumn(_router.availability_zone_hints),
         format_columns.ListColumn(_router.availability_zones),
+        _router.created_at,
         _router.description,
-        _router.distributed,
+        _router.is_distributed,
+        _router.enable_ndp_proxy,
         router.RouterInfoColumn(_router.external_gateway_info),
-        _router.ha,
+        _router.flavor_id,
+        _router.is_ha,
         _router.id,
         router.RouterInfoColumn(_router.interfaces_info),
         _router.name,
         _router.project_id,
+        _router.revision_number,
         router.RoutesColumn(_router.routes),
         _router.status,
         format_columns.ListColumn(_router.tags),
+        _router.updated_at,
     )
 
     def setUp(self):
@@ -1825,7 +1896,7 @@ class TestShowRouter(TestRouter):
         self.assertCountEqual(self.data, data)
 
     def test_show_no_ha_no_distributed(self):
-        _router = network_fakes.FakeRouter.create_one_router(
+        _router = network_fakes.create_one_router(
             {'ha': None, 'distributed': None}
         )
 
@@ -1846,7 +1917,7 @@ class TestShowRouter(TestRouter):
         self.assertNotIn("is_ha", columns)
 
     def test_show_no_extra_route_extension(self):
-        _router = network_fakes.FakeRouter.create_one_router({'routes': None})
+        _router = network_fakes.create_one_router({'routes': None})
 
         arglist = [
             _router.name,
@@ -1869,10 +1940,8 @@ class TestUnsetRouter(TestRouter):
     def setUp(self):
         super().setUp()
         self.fake_network = network_fakes.create_one_network()
-        self.fake_qos_policy = (
-            network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
-        )
-        self._testrouter = network_fakes.FakeRouter.create_one_router(
+        self.fake_qos_policy = network_fakes.create_one_qos_policy()
+        self._testrouter = network_fakes.create_one_router(
             {
                 'routes': [
                     {
@@ -2039,11 +2108,11 @@ class TestUnsetRouter(TestRouter):
         self.assertIsNone(result)
 
     def test_unset_gateway_ip_qos_no_network(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
-        router = network_fakes.FakeRouter.create_one_router()
+        router = network_fakes.create_one_router()
         self.network_client.find_router = mock.Mock(return_value=router)
         arglist = [
             "--qos-policy",
@@ -2059,11 +2128,11 @@ class TestUnsetRouter(TestRouter):
         )
 
     def test_unset_gateway_ip_qos_no_qos(self):
-        qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
+        qos_policy = network_fakes.create_one_qos_policy()
         self.network_client.find_qos_policy = mock.Mock(
             return_value=qos_policy
         )
-        router = network_fakes.FakeRouter.create_one_router(
+        router = network_fakes.create_one_router(
             {"external_gateway_info": {"network_id": "fake-id"}}
         )
         self.network_client.find_router = mock.Mock(return_value=router)
@@ -2088,7 +2157,7 @@ class TestGatewayOps(TestRouter):
         self._network = network_fakes.create_one_network()
         self._networks.append(self._network)
 
-        self._router = network_fakes.FakeRouter.create_one_router(
+        self._router = network_fakes.create_one_router(
             {
                 'external_gateway_info': {
                     'network_id': self._network.id,
@@ -2132,16 +2201,21 @@ class TestCreateMultipleGateways(TestGat
         'admin_state_up',
         'availability_zone_hints',
         'availability_zones',
+        'created_at',
         'description',
         'distributed',
+        'enable_ndp_proxy',
         'external_gateway_info',
+        'flavor_id',
         'ha',
         'id',
         'name',
         'project_id',
+        'revision_number',
         'routes',
         'status',
         'tags',
+        'updated_at',
     )
 
     def setUp(self):
@@ -2158,19 +2232,24 @@ class TestCreateMultipleGateways(TestGat
         )
 
         self._data = (
-            router.AdminStateColumn(self._router.admin_state_up),
+            router.AdminStateColumn(self._router.is_admin_state_up),
             format_columns.ListColumn(self._router.availability_zone_hints),
             format_columns.ListColumn(self._router.availability_zones),
+            self._router.created_at,
             self._router.description,
-            self._router.distributed,
+            self._router.is_distributed,
+            self._router.enable_ndp_proxy,
             router.RouterInfoColumn(self._router.external_gateway_info),
-            self._router.ha,
+            self._router.flavor_id,
+            self._router.is_ha,
             self._router.id,
             self._router.name,
             self._router.project_id,
+            self._router.revision_number,
             router.RoutesColumn(self._router.routes),
             self._router.status,
             format_columns.ListColumn(self._router.tags),
+            self._router.updated_at,
         )
         self.cmd = router.CreateRouter(self.app, None)
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_compute.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_compute.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_compute.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_compute.py	2025-07-07 22:41:56.000000000 +0000
@@ -72,7 +72,7 @@ class TestCreateSecurityGroupCompute(com
         columns, data = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             self._security_group['name'],
             self._security_group['name'],
         )
@@ -95,7 +95,7 @@ class TestCreateSecurityGroupCompute(com
         columns, data = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             self._security_group['name'],
             self._security_group['description'],
         )
@@ -133,7 +133,7 @@ class TestDeleteSecurityGroupCompute(com
         result = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             self._security_groups[0]['id'],
         )
         self.assertIsNone(result)
@@ -153,12 +153,8 @@ class TestDeleteSecurityGroupCompute(com
 
         sg_mock.assert_has_calls(
             [
-                mock.call(
-                    self.compute_sdk_client, self._security_groups[0]['id']
-                ),
-                mock.call(
-                    self.compute_sdk_client, self._security_groups[1]['id']
-                ),
+                mock.call(self.compute_client, self._security_groups[0]['id']),
+                mock.call(self.compute_client, self._security_groups[1]['id']),
             ]
         )
         self.assertIsNone(result)
@@ -187,9 +183,7 @@ class TestDeleteSecurityGroupCompute(com
 
         sg_mock.assert_has_calls(
             [
-                mock.call(
-                    self.compute_sdk_client, self._security_groups[0]['id']
-                ),
+                mock.call(self.compute_client, self._security_groups[0]['id']),
             ]
         )
 
@@ -250,7 +244,7 @@ class TestListSecurityGroupCompute(compu
         columns, data = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client, all_projects=False
+            self.compute_client, all_projects=False
         )
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, list(data))
@@ -267,9 +261,7 @@ class TestListSecurityGroupCompute(compu
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        sg_mock.assert_called_once_with(
-            self.compute_sdk_client, all_projects=True
-        )
+        sg_mock.assert_called_once_with(self.compute_client, all_projects=True)
         self.assertEqual(self.columns_all_projects, columns)
         self.assertCountEqual(self.data_all_projects, list(data))
 
@@ -309,7 +301,7 @@ class TestSetSecurityGroupCompute(comput
         result = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client, self._security_group['id']
+            self.compute_client, self._security_group['id']
         )
         self.assertIsNone(result)
 
@@ -334,7 +326,7 @@ class TestSetSecurityGroupCompute(comput
         result = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             self._security_group['id'],
             name=new_name,
             description=new_description,
@@ -394,7 +386,7 @@ class TestShowSecurityGroupCompute(compu
         columns, data = self.cmd.take_action(parsed_args)
 
         sg_mock.assert_called_once_with(
-            self.compute_sdk_client, self._security_group['id']
+            self.compute_client, self._security_group['id']
         )
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_network.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_network.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_network.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_network.py	2025-07-07 22:41:56.000000000 +0000
@@ -36,28 +36,32 @@ class TestCreateSecurityGroupNetwork(Tes
     project = identity_fakes.FakeProject.create_one_project()
     domain = identity_fakes.FakeDomain.create_one_domain()
     # The security group to be created.
-    _security_group = (
-        network_fakes.FakeSecurityGroup.create_one_security_group()
-    )
+    _security_group = network_fakes.create_one_security_group()
 
     columns = (
+        'created_at',
         'description',
         'id',
         'name',
         'project_id',
+        'revision_number',
         'rules',
         'stateful',
         'tags',
+        'updated_at',
     )
 
     data = (
+        _security_group.created_at,
         _security_group.description,
         _security_group.id,
         _security_group.name,
         _security_group.project_id,
+        _security_group.revision_number,
         security_group.NetworkSecurityGroupRulesColumn([]),
         _security_group.stateful,
         _security_group.tags,
+        _security_group.updated_at,
     )
 
     def setUp(self):
@@ -163,7 +167,7 @@ class TestCreateSecurityGroupNetwork(Tes
         else:
             self.assertFalse(self.network_client.set_tags.called)
         self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, data)
+        self.assertEqual(self.data, data)
 
     def test_create_with_tags(self):
         self._test_create_with_tag(add_tags=True)
@@ -174,7 +178,7 @@ class TestCreateSecurityGroupNetwork(Tes
 
 class TestDeleteSecurityGroupNetwork(TestSecurityGroupNetwork):
     # The security groups to be deleted.
-    _security_groups = network_fakes.FakeSecurityGroup.create_security_groups()
+    _security_groups = network_fakes.create_security_groups()
 
     def setUp(self):
         super().setUp()
@@ -184,9 +188,7 @@ class TestDeleteSecurityGroupNetwork(Tes
         )
 
         self.network_client.find_security_group = (
-            network_fakes.FakeSecurityGroup.get_security_groups(
-                self._security_groups
-            )
+            network_fakes.get_security_groups(self._security_groups)
         )
 
         # Get the command object to test
@@ -264,9 +266,7 @@ class TestDeleteSecurityGroupNetwork(Tes
 
 class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
     # The security group to be listed.
-    _security_groups = network_fakes.FakeSecurityGroup.create_security_groups(
-        count=3
-    )
+    _security_groups = network_fakes.create_security_groups(count=3)
 
     columns = (
         'ID',
@@ -412,10 +412,8 @@ class TestListSecurityGroupNetwork(TestS
 
 class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
     # The security group to be set.
-    _security_group = (
-        network_fakes.FakeSecurityGroup.create_one_security_group(
-            attrs={'tags': ['green', 'red']}
-        )
+    _security_group = network_fakes.create_one_security_group(
+        attrs={'tags': ['green', 'red']}
     )
 
     def setUp(self):
@@ -515,37 +513,39 @@ class TestSetSecurityGroupNetwork(TestSe
 
 class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
     # The security group rule to be shown with the group.
-    _security_group_rule = (
-        network_fakes.FakeSecurityGroupRule.create_one_security_group_rule()
-    )
+    _security_group_rule = network_fakes.create_one_security_group_rule()
 
     # The security group to be shown.
-    _security_group = (
-        network_fakes.FakeSecurityGroup.create_one_security_group(
-            attrs={'security_group_rules': [_security_group_rule._info]}
-        )
+    _security_group = network_fakes.create_one_security_group(
+        attrs={'security_group_rules': [dict(_security_group_rule)]}
     )
 
     columns = (
+        'created_at',
         'description',
         'id',
         'name',
         'project_id',
+        'revision_number',
         'rules',
         'stateful',
         'tags',
+        'updated_at',
     )
 
     data = (
+        _security_group.created_at,
         _security_group.description,
         _security_group.id,
         _security_group.name,
         _security_group.project_id,
+        _security_group.revision_number,
         security_group.NetworkSecurityGroupRulesColumn(
-            [_security_group_rule._info]
+            [dict(_security_group_rule)]
         ),
         _security_group.stateful,
         _security_group.tags,
+        _security_group.updated_at,
     )
 
     def setUp(self):
@@ -583,10 +583,8 @@ class TestShowSecurityGroupNetwork(TestS
 
 class TestUnsetSecurityGroupNetwork(TestSecurityGroupNetwork):
     # The security group to be unset.
-    _security_group = (
-        network_fakes.FakeSecurityGroup.create_one_security_group(
-            attrs={'tags': ['green', 'red']}
-        )
+    _security_group = network_fakes.create_one_security_group(
+        attrs={'tags': ['green', 'red']}
     )
 
     def setUp(self):
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py	2025-07-07 22:41:56.000000000 +0000
@@ -159,7 +159,7 @@ class TestCreateSecurityGroupRuleCompute
         columns, data = self.cmd.take_action(parsed_args)
 
         sgr_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             security_group_id=self._security_group['id'],
             ip_protocol=self._security_group_rule['ip_protocol'],
             from_port=self._security_group_rule['from_port'],
@@ -202,7 +202,7 @@ class TestCreateSecurityGroupRuleCompute
         columns, data = self.cmd.take_action(parsed_args)
 
         sgr_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             security_group_id=self._security_group['id'],
             ip_protocol=self._security_group_rule['ip_protocol'],
             from_port=self._security_group_rule['from_port'],
@@ -240,7 +240,7 @@ class TestCreateSecurityGroupRuleCompute
         columns, data = self.cmd.take_action(parsed_args)
 
         sgr_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             security_group_id=self._security_group['id'],
             ip_protocol=self._security_group_rule['ip_protocol'],
             from_port=self._security_group_rule['from_port'],
@@ -279,7 +279,7 @@ class TestCreateSecurityGroupRuleCompute
         columns, data = self.cmd.take_action(parsed_args)
 
         sgr_mock.assert_called_once_with(
-            self.compute_sdk_client,
+            self.compute_client,
             security_group_id=self._security_group['id'],
             ip_protocol=self._security_group_rule['ip_protocol'],
             from_port=self._security_group_rule['from_port'],
@@ -316,7 +316,7 @@ class TestDeleteSecurityGroupRuleCompute
         result = self.cmd.take_action(parsed_args)
 
         sgr_mock.assert_called_once_with(
-            self.compute_sdk_client, self._security_group_rules[0]['id']
+            self.compute_client, self._security_group_rules[0]['id']
         )
         self.assertIsNone(result)
 
@@ -335,11 +335,11 @@ class TestDeleteSecurityGroupRuleCompute
         sgr_mock.assert_has_calls(
             [
                 mock.call(
-                    self.compute_sdk_client,
+                    self.compute_client,
                     self._security_group_rules[0]['id'],
                 ),
                 mock.call(
-                    self.compute_sdk_client,
+                    self.compute_client,
                     self._security_group_rules[1]['id'],
                 ),
             ]
@@ -367,10 +367,10 @@ class TestDeleteSecurityGroupRuleCompute
         sgr_mock.assert_has_calls(
             [
                 mock.call(
-                    self.compute_sdk_client,
+                    self.compute_client,
                     self._security_group_rules[0]['id'],
                 ),
-                mock.call(self.compute_sdk_client, 'unexist_rule'),
+                mock.call(self.compute_client, 'unexist_rule'),
             ]
         )
 
@@ -383,7 +383,6 @@ class TestListSecurityGroupRuleCompute(c
     _security_group_rule_tcp = compute_fakes.create_one_security_group_rule(
         {
             'ip_protocol': 'tcp',
-            'ethertype': 'IPv4',
             'from_port': 80,
             'to_port': 80,
             'group': {'name': _security_group['name']},
@@ -392,7 +391,6 @@ class TestListSecurityGroupRuleCompute(c
     _security_group_rule_icmp = compute_fakes.create_one_security_group_rule(
         {
             'ip_protocol': 'icmp',
-            'ethertype': 'IPv4',
             'from_port': -1,
             'to_port': -1,
             'ip_range': {'cidr': '10.0.2.0/24'},
@@ -426,7 +424,7 @@ class TestListSecurityGroupRuleCompute(c
         expected_rule_with_group = (
             rule['id'],
             rule['ip_protocol'],
-            rule['ethertype'],
+            '',  # ethertype is a neutron-only thing
             rule['ip_range'],
             rule['port_range'],
             rule['remote_security_group'],
@@ -457,7 +455,7 @@ class TestListSecurityGroupRuleCompute(c
 
         columns, data = self.cmd.take_action(parsed_args)
         compute_v2.list_security_groups.assert_called_once_with(
-            self.compute_sdk_client, all_projects=False
+            self.compute_client, all_projects=False
         )
         self.assertEqual(self.expected_columns_no_group, columns)
         self.assertEqual(self.expected_data_no_group, list(data))
@@ -473,7 +471,7 @@ class TestListSecurityGroupRuleCompute(c
 
         columns, data = self.cmd.take_action(parsed_args)
         compute_v2.find_security_group.assert_called_once_with(
-            self.compute_sdk_client, self._security_group['id']
+            self.compute_client, self._security_group['id']
         )
         self.assertEqual(self.expected_columns_with_group, columns)
         self.assertEqual(self.expected_data_with_group, list(data))
@@ -489,7 +487,7 @@ class TestListSecurityGroupRuleCompute(c
 
         columns, data = self.cmd.take_action(parsed_args)
         compute_v2.list_security_groups.assert_called_once_with(
-            self.compute_sdk_client, all_projects=True
+            self.compute_client, all_projects=True
         )
         self.assertEqual(self.expected_columns_no_group, columns)
         self.assertEqual(self.expected_data_no_group, list(data))
@@ -505,7 +503,7 @@ class TestListSecurityGroupRuleCompute(c
 
         columns, data = self.cmd.take_action(parsed_args)
         compute_v2.list_security_groups.assert_called_once_with(
-            self.compute_sdk_client, all_projects=False
+            self.compute_client, all_projects=False
         )
         self.assertEqual(self.expected_columns_no_group, columns)
         self.assertEqual(self.expected_data_no_group, list(data))
@@ -551,7 +549,7 @@ class TestShowSecurityGroupRuleCompute(c
         columns, data = self.cmd.take_action(parsed_args)
 
         compute_v2.list_security_groups.assert_called_once_with(
-            self.compute_sdk_client
+            self.compute_client
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
--- 7.4.0-3/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/network/v2/test_security_group_rule_network.py	2025-07-07 22:41:56.000000000 +0000
@@ -40,14 +40,13 @@ class TestCreateSecurityGroupRuleNetwork
     _security_group_rule = None
 
     # The security group that will contain the rule created.
-    _security_group = (
-        network_fakes.FakeSecurityGroup.create_one_security_group()
-    )
+    _security_group = network_fakes.create_one_security_group()
 
     # The address group to be used in security group rules
     _address_group = network_fakes.create_one_address_group()
 
     expected_columns = (
+        'created_at',
         'description',
         'direction',
         'ether_type',
@@ -59,21 +58,22 @@ class TestCreateSecurityGroupRuleNetwork
         'remote_address_group_id',
         'remote_group_id',
         'remote_ip_prefix',
+        'revision_number',
         'security_group_id',
+        'updated_at',
     )
 
     expected_data = None
 
     def _setup_security_group_rule(self, attrs=None):
         self._security_group_rule = (
-            network_fakes.FakeSecurityGroupRule.create_one_security_group_rule(
-                attrs
-            )
+            network_fakes.create_one_security_group_rule(attrs)
         )
         self.network_client.create_security_group_rule = mock.Mock(
             return_value=self._security_group_rule
         )
         self.expected_data = (
+            self._security_group_rule.created_at,
             self._security_group_rule.description,
             self._security_group_rule.direction,
             self._security_group_rule.ether_type,
@@ -85,7 +85,9 @@ class TestCreateSecurityGroupRuleNetwork
             self._security_group_rule.remote_address_group_id,
             self._security_group_rule.remote_group_id,
             self._security_group_rule.remote_ip_prefix,
+            self._security_group_rule.revision_number,
             self._security_group_rule.security_group_id,
+            self._security_group_rule.updated_at,
         )
 
     def setUp(self):
@@ -963,11 +965,7 @@ class TestCreateSecurityGroupRuleNetwork
 
 class TestDeleteSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
     # The security group rules to be deleted.
-    _security_group_rules = (
-        network_fakes.FakeSecurityGroupRule.create_security_group_rules(
-            count=2
-        )
-    )
+    _security_group_rules = network_fakes.create_security_group_rules(count=2)
 
     def setUp(self):
         super().setUp()
@@ -977,9 +975,7 @@ class TestDeleteSecurityGroupRuleNetwork
         )
 
         self.network_client.find_security_group_rule = (
-            network_fakes.FakeSecurityGroupRule.get_security_group_rules(
-                self._security_group_rules
-            )
+            network_fakes.get_security_group_rules(self._security_group_rules)
         )
 
         # Get the command object to test
@@ -1057,33 +1053,27 @@ class TestDeleteSecurityGroupRuleNetwork
 
 class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
     # The security group to hold the rules.
-    _security_group = (
-        network_fakes.FakeSecurityGroup.create_one_security_group()
-    )
+    _security_group = network_fakes.create_one_security_group()
 
     # The security group rule to be listed.
-    _security_group_rule_tcp = (
-        network_fakes.FakeSecurityGroupRule.create_one_security_group_rule(
-            {
-                'protocol': 'tcp',
-                'port_range_max': 80,
-                'port_range_min': 80,
-                'security_group_id': _security_group.id,
-            }
-        )
+    _security_group_rule_tcp = network_fakes.create_one_security_group_rule(
+        {
+            'protocol': 'tcp',
+            'port_range_max': 80,
+            'port_range_min': 80,
+            'security_group_id': _security_group.id,
+        }
     )
-    _security_group_rule_icmp = (
-        network_fakes.FakeSecurityGroupRule.create_one_security_group_rule(
-            {
-                'protocol': 'icmp',
-                'remote_ip_prefix': '10.0.2.0/24',
-                'security_group_id': _security_group.id,
-            }
-        )
+    _security_group_rule_icmp = network_fakes.create_one_security_group_rule(
+        {
+            'protocol': 'icmp',
+            'remote_ip_prefix': '10.0.2.0/24',
+            'security_group_id': _security_group.id,
+        }
     )
     _security_group.security_group_rules = [
-        _security_group_rule_tcp._info,
-        _security_group_rule_icmp._info,
+        dict(_security_group_rule_tcp),
+        dict(_security_group_rule_icmp),
     ]
     _security_group_rules = [
         _security_group_rule_tcp,
@@ -1264,11 +1254,10 @@ class TestListSecurityGroupRuleNetwork(T
 
 class TestShowSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
     # The security group rule to be shown.
-    _security_group_rule = (
-        network_fakes.FakeSecurityGroupRule.create_one_security_group_rule()
-    )
+    _security_group_rule = network_fakes.create_one_security_group_rule()
 
     columns = (
+        'created_at',
         'description',
         'direction',
         'ether_type',
@@ -1280,10 +1269,13 @@ class TestShowSecurityGroupRuleNetwork(T
         'remote_address_group_id',
         'remote_group_id',
         'remote_ip_prefix',
+        'revision_number',
         'security_group_id',
+        'updated_at',
     )
 
     data = (
+        _security_group_rule.created_at,
         _security_group_rule.description,
         _security_group_rule.direction,
         _security_group_rule.ether_type,
@@ -1295,7 +1287,9 @@ class TestShowSecurityGroupRuleNetwork(T
         _security_group_rule.remote_address_group_id,
         _security_group_rule.remote_group_id,
         _security_group_rule.remote_ip_prefix,
+        _security_group_rule.revision_number,
         _security_group_rule.security_group_id,
+        _security_group_rule.updated_at,
     )
 
     def setUp(self):
diff -pruN 7.4.0-3/openstackclient/tests/unit/object/v1/test_object_all.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/object/v1/test_object_all.py
--- 7.4.0-3/openstackclient/tests/unit/object/v1/test_object_all.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/object/v1/test_object_all.py	2025-07-07 22:41:56.000000000 +0000
@@ -252,9 +252,10 @@ class TestObjectSave(TestObjectAll):
             def __exit__(self, *a):
                 self.context_manager_calls.append('__exit__')
 
-        with mock.patch('sys.stdout') as fake_stdout, mock.patch(
-            'os.fdopen', return_value=FakeStdout()
-        ) as fake_fdopen:
+        with (
+            mock.patch('sys.stdout') as fake_stdout,
+            mock.patch('os.fdopen', return_value=FakeStdout()) as fake_fdopen,
+        ):
             fake_stdout.fileno.return_value = 123
             self.cmd.take_action(parsed_args)
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/test_shell.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/test_shell.py
--- 7.4.0-3/openstackclient/tests/unit/test_shell.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/test_shell.py	2025-07-07 22:41:56.000000000 +0000
@@ -183,14 +183,14 @@ class TestShell(osc_lib_test_utils.TestS
             osc_lib_test_utils.fake_execute(_shell, _cmd)
 
             self.app.assert_called_with(["list", "role"])
-            self.assertEqual(
-                default_args.get("token", ''), _shell.options.token, "token"
-            )
-            self.assertEqual(
-                default_args.get("auth_url", ''),
-                _shell.options.auth_url,
-                "auth_url",
-            )
+
+            if default_args.get('token'):
+                self.assertEqual(default_args['token'], _shell.options.token)
+
+            if default_args.get('auth_url'):
+                self.assertEqual(
+                    default_args['auth_url'], _shell.options.auth_url
+                )
 
     def _assert_cli(self, cmd_options, default_args):
         with mock.patch(
@@ -204,25 +204,28 @@ class TestShell(osc_lib_test_utils.TestS
             osc_lib_test_utils.fake_execute(_shell, _cmd)
 
             self.app.assert_called_with(["list", "server"])
+
+            # TODO(stephenfin): Remove "or ''" when we bump osc-lib minimum to
+            # a version that includes I1d26133c9d9ed299d1035f207059aa8fe463a001
             self.assertEqual(
                 default_args["compute_api_version"],
-                _shell.options.os_compute_api_version,
+                _shell.options.os_compute_api_version or '',
             )
             self.assertEqual(
                 default_args["identity_api_version"],
-                _shell.options.os_identity_api_version,
+                _shell.options.os_identity_api_version or '',
             )
             self.assertEqual(
                 default_args["image_api_version"],
-                _shell.options.os_image_api_version,
+                _shell.options.os_image_api_version or '',
             )
             self.assertEqual(
                 default_args["volume_api_version"],
-                _shell.options.os_volume_api_version,
+                _shell.options.os_volume_api_version or '',
             )
             self.assertEqual(
                 default_args["network_api_version"],
-                _shell.options.os_network_api_version,
+                _shell.options.os_network_api_version or '',
             )
 
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/fakes.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,615 +0,0 @@
-#   Copyright 2013 Nebula Inc.
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-import copy
-import random
-from unittest import mock
-import uuid
-
-from openstack.image.v1 import _proxy as image_v1_proxy
-
-from openstackclient.tests.unit import fakes
-from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
-from openstackclient.tests.unit import utils
-
-
-class FakeVolumev1Client:
-    def __init__(self, **kwargs):
-        self.volumes = mock.Mock()
-        self.volumes.resource_class = fakes.FakeResource(None, {})
-        self.services = mock.Mock()
-        self.services.resource_class = fakes.FakeResource(None, {})
-        self.extensions = mock.Mock()
-        self.extensions.resource_class = fakes.FakeResource(None, {})
-        self.qos_specs = mock.Mock()
-        self.qos_specs.resource_class = fakes.FakeResource(None, {})
-        self.volume_types = mock.Mock()
-        self.volume_types.resource_class = fakes.FakeResource(None, {})
-        self.volume_encryption_types = mock.Mock()
-        self.volume_encryption_types.resource_class = fakes.FakeResource(
-            None, {}
-        )
-        self.transfers = mock.Mock()
-        self.transfers.resource_class = fakes.FakeResource(None, {})
-        self.volume_snapshots = mock.Mock()
-        self.volume_snapshots.resource_class = fakes.FakeResource(None, {})
-        self.backups = mock.Mock()
-        self.backups.resource_class = fakes.FakeResource(None, {})
-        self.restores = mock.Mock()
-        self.restores.resource_class = fakes.FakeResource(None, {})
-        self.auth_token = kwargs['token']
-        self.management_url = kwargs['endpoint']
-
-
-class FakeClientMixin:
-    def setUp(self):
-        super().setUp()
-
-        self.app.client_manager.volume = FakeVolumev1Client(
-            endpoint=fakes.AUTH_URL,
-            token=fakes.AUTH_TOKEN,
-        )
-        self.volume_client = self.app.client_manager.volume
-
-
-class TestVolumev1(
-    identity_fakes.FakeClientMixin,
-    FakeClientMixin,
-    utils.TestCommand,
-):
-    def setUp(self):
-        super().setUp()
-
-        # avoid circular imports by defining this manually rather than using
-        # openstackclient.tests.unit.image.v1.fakes.FakeClientMixin
-        self.app.client_manager.image = mock.Mock(spec=image_v1_proxy.Proxy)
-        self.image_client = self.app.client_manager.image
-
-
-def create_one_transfer(attrs=None):
-    """Create a fake transfer.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes of Transfer Request
-    :return:
-        A FakeResource object with volume_id, name, id.
-    """
-    # Set default attribute
-    transfer_info = {
-        'volume_id': 'volume-id-' + uuid.uuid4().hex,
-        'name': 'fake_transfer_name',
-        'id': 'id-' + uuid.uuid4().hex,
-        'links': 'links-' + uuid.uuid4().hex,
-    }
-
-    # Overwrite default attributes if there are some attributes set
-    attrs = attrs or {}
-
-    transfer_info.update(attrs)
-
-    transfer = fakes.FakeResource(None, transfer_info, loaded=True)
-
-    return transfer
-
-
-def create_transfers(attrs=None, count=2):
-    """Create multiple fake transfers.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes of transfer
-    :param Integer count:
-        The number of transfers to be faked
-    :return:
-        A list of FakeResource objects
-    """
-    transfers = []
-    for n in range(0, count):
-        transfers.append(create_one_transfer(attrs))
-
-    return transfers
-
-
-def get_transfers(transfers=None, count=2):
-    """Get an iterable MagicMock object with a list of faked transfers.
-
-    If transfers list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List transfers:
-        A list of FakeResource objects faking transfers
-    :param Integer count:
-        The number of transfers to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        transfers
-    """
-    if transfers is None:
-        transfers = create_transfers(count)
-
-    return mock.Mock(side_effect=transfers)
-
-
-def create_one_service(attrs=None):
-    """Create a fake service.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes of service
-    :return:
-        A FakeResource object with host, status, etc.
-    """
-    # Set default attribute
-    service_info = {
-        'host': 'host_test',
-        'binary': 'cinder_test',
-        'status': 'enabled',
-        'disabled_reason': 'LongHoliday-GoldenWeek',
-        'zone': 'fake_zone',
-        'updated_at': 'fake_date',
-        'state': 'fake_state',
-    }
-
-    # Overwrite default attributes if there are some attributes set
-    attrs = attrs or {}
-
-    service_info.update(attrs)
-
-    service = fakes.FakeResource(None, service_info, loaded=True)
-
-    return service
-
-
-def create_services(attrs=None, count=2):
-    """Create multiple fake services.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes of service
-    :param Integer count:
-        The number of services to be faked
-    :return:
-        A list of FakeResource objects
-    """
-    services = []
-    for n in range(0, count):
-        services.append(create_one_service(attrs))
-
-    return services
-
-
-def get_services(services=None, count=2):
-    """Get an iterable MagicMock object with a list of faked services.
-
-    If services list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List services:
-        A list of FakeResource objects faking services
-    :param Integer count:
-        The number of services to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        services
-    """
-    if services is None:
-        services = create_services(count)
-
-    return mock.Mock(side_effect=services)
-
-
-def create_one_qos(attrs=None):
-    """Create a fake Qos specification.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object with id, name, consumer, etc.
-    """
-    attrs = attrs or {}
-
-    # Set default attributes.
-    qos_info = {
-        "id": 'qos-id-' + uuid.uuid4().hex,
-        "name": 'qos-name-' + uuid.uuid4().hex,
-        "consumer": 'front-end',
-        "specs": {"foo": "bar", "iops": "9001"},
-    }
-
-    # Overwrite default attributes.
-    qos_info.update(attrs)
-
-    qos = fakes.FakeResource(info=copy.deepcopy(qos_info), loaded=True)
-    return qos
-
-
-def create_one_qos_association(attrs=None):
-    """Create a fake Qos specification association.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object with id, name, association_type, etc.
-    """
-    attrs = attrs or {}
-
-    # Set default attributes.
-    qos_association_info = {
-        "id": 'type-id-' + uuid.uuid4().hex,
-        "name": 'type-name-' + uuid.uuid4().hex,
-        "association_type": 'volume_type',
-    }
-
-    # Overwrite default attributes.
-    qos_association_info.update(attrs)
-
-    qos_association = fakes.FakeResource(
-        info=copy.deepcopy(qos_association_info), loaded=True
-    )
-    return qos_association
-
-
-def create_qoses(attrs=None, count=2):
-    """Create multiple fake Qos specifications.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of Qos specifications to fake
-    :return:
-        A list of FakeResource objects faking the Qos specifications
-    """
-    qoses = []
-    for i in range(0, count):
-        qos = create_one_qos(attrs)
-        qoses.append(qos)
-
-    return qoses
-
-
-def get_qoses(qoses=None, count=2):
-    """Get an iterable MagicMock object with a list of faked qoses.
-
-    If qoses list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List volumes:
-        A list of FakeResource objects faking qoses
-    :param Integer count:
-        The number of qoses to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        qoses
-    """
-    if qoses is None:
-        qoses = create_qoses(count)
-
-    return mock.Mock(side_effect=qoses)
-
-
-def create_one_volume(attrs=None):
-    """Create a fake volume.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes of volume
-    :return:
-        A FakeResource object with id, name, status, etc.
-    """
-    attrs = attrs or {}
-
-    # Set default attribute
-    volume_info = {
-        'id': 'volume-id' + uuid.uuid4().hex,
-        'display_name': 'volume-name' + uuid.uuid4().hex,
-        'display_description': 'description' + uuid.uuid4().hex,
-        'status': 'available',
-        'size': 10,
-        'volume_type': random.choice(['fake_lvmdriver-1', 'fake_lvmdriver-2']),
-        'bootable': 'true',
-        'metadata': {
-            'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
-            'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
-            'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex,
-        },
-        'snapshot_id': 'snapshot-id-' + uuid.uuid4().hex,
-        'availability_zone': 'zone' + uuid.uuid4().hex,
-        'attachments': [
-            {
-                'device': '/dev/' + uuid.uuid4().hex,
-                'server_id': uuid.uuid4().hex,
-            },
-        ],
-        'created_at': 'time-' + uuid.uuid4().hex,
-    }
-
-    # Overwrite default attributes if there are some attributes set
-    volume_info.update(attrs)
-
-    volume = fakes.FakeResource(None, volume_info, loaded=True)
-    return volume
-
-
-def create_volumes(attrs=None, count=2):
-    """Create multiple fake volumes.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes of volume
-    :param Integer count:
-        The number of volumes to be faked
-    :return:
-        A list of FakeResource objects
-    """
-    volumes = []
-    for n in range(0, count):
-        volumes.append(create_one_volume(attrs))
-
-    return volumes
-
-
-def get_volumes(volumes=None, count=2):
-    """Get an iterable MagicMock object with a list of faked volumes.
-
-    If volumes list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List volumes:
-        A list of FakeResource objects faking volumes
-    :param Integer count:
-        The number of volumes to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        volumes
-    """
-    if volumes is None:
-        volumes = create_volumes(count)
-
-    return mock.Mock(side_effect=volumes)
-
-
-def create_one_volume_type(attrs=None, methods=None):
-    """Create a fake volume type.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :param Dictionary methods:
-        A dictionary with all methods
-    :return:
-        A FakeResource object with id, name, description, etc.
-    """
-    attrs = attrs or {}
-    methods = methods or {}
-
-    # Set default attributes.
-    volume_type_info = {
-        "id": 'type-id-' + uuid.uuid4().hex,
-        "name": 'type-name-' + uuid.uuid4().hex,
-        "description": 'type-description-' + uuid.uuid4().hex,
-        "extra_specs": {"foo": "bar"},
-        "is_public": True,
-    }
-
-    # Overwrite default attributes.
-    volume_type_info.update(attrs)
-
-    volume_type = fakes.FakeResource(
-        info=copy.deepcopy(volume_type_info), methods=methods, loaded=True
-    )
-    return volume_type
-
-
-def create_volume_types(attrs=None, count=2):
-    """Create multiple fake types.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of types to fake
-    :return:
-        A list of FakeResource objects faking the types
-    """
-    volume_types = []
-    for i in range(0, count):
-        volume_type = create_one_volume_type(attrs)
-        volume_types.append(volume_type)
-
-    return volume_types
-
-
-def get_volume_types(volume_types=None, count=2):
-    """Get an iterable MagicMock object with a list of faked types.
-
-    If types list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List volume_types:
-        A list of FakeResource objects faking types
-    :param Integer count:
-        The number of types to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        types
-    """
-    if volume_types is None:
-        volume_types = create_volume_types(count)
-
-    return mock.Mock(side_effect=volume_types)
-
-
-def create_one_encryption_volume_type(attrs=None):
-    """Create a fake encryption volume type.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object with volume_type_id etc.
-    """
-    attrs = attrs or {}
-
-    # Set default attributes.
-    encryption_info = {
-        "volume_type_id": 'type-id-' + uuid.uuid4().hex,
-        'provider': 'LuksEncryptor',
-        'cipher': None,
-        'key_size': None,
-        'control_location': 'front-end',
-    }
-
-    # Overwrite default attributes.
-    encryption_info.update(attrs)
-
-    encryption_type = fakes.FakeResource(
-        info=copy.deepcopy(encryption_info), loaded=True
-    )
-    return encryption_type
-
-
-def create_one_snapshot(attrs=None):
-    """Create a fake snapshot.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object with id, name, description, etc.
-    """
-    attrs = attrs or {}
-
-    # Set default attributes.
-    snapshot_info = {
-        "id": 'snapshot-id-' + uuid.uuid4().hex,
-        "display_name": 'snapshot-name-' + uuid.uuid4().hex,
-        "display_description": 'snapshot-description-' + uuid.uuid4().hex,
-        "size": 10,
-        "status": "available",
-        "metadata": {"foo": "bar"},
-        "created_at": "2015-06-03T18:49:19.000000",
-        "volume_id": 'vloume-id-' + uuid.uuid4().hex,
-    }
-
-    # Overwrite default attributes.
-    snapshot_info.update(attrs)
-
-    snapshot_method = {'update': None}
-
-    snapshot = fakes.FakeResource(
-        info=copy.deepcopy(snapshot_info),
-        methods=copy.deepcopy(snapshot_method),
-        loaded=True,
-    )
-    return snapshot
-
-
-def create_snapshots(attrs=None, count=2):
-    """Create multiple fake snapshots.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of snapshots to fake
-    :return:
-        A list of FakeResource objects faking the snapshots
-    """
-    snapshots = []
-    for i in range(0, count):
-        snapshot = create_one_snapshot(attrs)
-        snapshots.append(snapshot)
-
-    return snapshots
-
-
-def get_snapshots(snapshots=None, count=2):
-    """Get an iterable MagicMock object with a list of faked snapshots.
-
-    If snapshots list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List volumes:
-        A list of FakeResource objects faking snapshots
-    :param Integer count:
-        The number of snapshots to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        snapshots
-    """
-    if snapshots is None:
-        snapshots = create_snapshots(count)
-
-    return mock.Mock(side_effect=snapshots)
-
-
-def create_one_backup(attrs=None):
-    """Create a fake backup.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :return:
-        A FakeResource object with id, name, volume_id, etc.
-    """
-    attrs = attrs or {}
-
-    # Set default attributes.
-    backup_info = {
-        "id": 'backup-id-' + uuid.uuid4().hex,
-        "name": 'backup-name-' + uuid.uuid4().hex,
-        "volume_id": 'volume-id-' + uuid.uuid4().hex,
-        "snapshot_id": 'snapshot-id' + uuid.uuid4().hex,
-        "description": 'description-' + uuid.uuid4().hex,
-        "object_count": None,
-        "container": 'container-' + uuid.uuid4().hex,
-        "size": random.randint(1, 20),
-        "status": "error",
-        "availability_zone": 'zone' + uuid.uuid4().hex,
-        "links": 'links-' + uuid.uuid4().hex,
-    }
-
-    # Overwrite default attributes.
-    backup_info.update(attrs)
-
-    backup = fakes.FakeResource(info=copy.deepcopy(backup_info), loaded=True)
-    return backup
-
-
-def create_backups(attrs=None, count=2):
-    """Create multiple fake backups.
-
-    :param Dictionary attrs:
-        A dictionary with all attributes
-    :param int count:
-        The number of backups to fake
-    :return:
-        A list of FakeResource objects faking the backups
-    """
-    backups = []
-    for i in range(0, count):
-        backup = create_one_backup(attrs)
-        backups.append(backup)
-
-    return backups
-
-
-def get_backups(backups=None, count=2):
-    """Get an iterable MagicMock object with a list of faked backups.
-
-    If backups list is provided, then initialize the Mock object with the
-    list. Otherwise create one.
-
-    :param List volumes:
-        A list of FakeResource objects faking backups
-    :param Integer count:
-        The number of backups to be faked
-    :return
-        An iterable Mock object with side_effect set to a list of faked
-        backups
-    """
-    if backups is None:
-        backups = create_backups(count)
-
-    return mock.Mock(side_effect=backups)
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/test_qos_specs.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_qos_specs.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/test_qos_specs.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_qos_specs.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,471 +0,0 @@
-#   Copyright 2015 iWeb Technologies Inc.
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-import copy
-from unittest import mock
-from unittest.mock import call
-
-from osc_lib.cli import format_columns
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import qos_specs
-
-
-class TestQos(volume_fakes.TestVolumev1):
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock = self.volume_client.qos_specs
-        self.qos_mock.reset_mock()
-
-        self.types_mock = self.volume_client.volume_types
-        self.types_mock.reset_mock()
-
-
-class TestQosAssociate(TestQos):
-    volume_type = volume_fakes.create_one_volume_type()
-    qos_spec = volume_fakes.create_one_qos()
-
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock.get.return_value = self.qos_spec
-        self.types_mock.get.return_value = self.volume_type
-        # Get the command object to test
-        self.cmd = qos_specs.AssociateQos(self.app, None)
-
-    def test_qos_associate(self):
-        arglist = [self.qos_spec.id, self.volume_type.id]
-        verifylist = [
-            ('qos_spec', self.qos_spec.id),
-            ('volume_type', self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.associate.assert_called_with(
-            self.qos_spec.id, self.volume_type.id
-        )
-        self.assertIsNone(result)
-
-
-class TestQosCreate(TestQos):
-    columns = ('consumer', 'id', 'name', 'properties')
-
-    def setUp(self):
-        super().setUp()
-        self.new_qos_spec = volume_fakes.create_one_qos()
-        self.datalist = (
-            self.new_qos_spec.consumer,
-            self.new_qos_spec.id,
-            self.new_qos_spec.name,
-            format_columns.DictColumn(self.new_qos_spec.specs),
-        )
-        self.qos_mock.create.return_value = self.new_qos_spec
-        # Get the command object to test
-        self.cmd = qos_specs.CreateQos(self.app, None)
-
-    def test_qos_create_without_properties(self):
-        arglist = [
-            self.new_qos_spec.name,
-        ]
-        verifylist = [
-            ('name', self.new_qos_spec.name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.create.assert_called_with(
-            self.new_qos_spec.name, {'consumer': 'both'}
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_qos_create_with_consumer(self):
-        arglist = [
-            '--consumer',
-            self.new_qos_spec.consumer,
-            self.new_qos_spec.name,
-        ]
-        verifylist = [
-            ('consumer', self.new_qos_spec.consumer),
-            ('name', self.new_qos_spec.name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.create.assert_called_with(
-            self.new_qos_spec.name, {'consumer': self.new_qos_spec.consumer}
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_qos_create_with_properties(self):
-        arglist = [
-            '--consumer',
-            self.new_qos_spec.consumer,
-            '--property',
-            'foo=bar',
-            '--property',
-            'iops=9001',
-            self.new_qos_spec.name,
-        ]
-        verifylist = [
-            ('consumer', self.new_qos_spec.consumer),
-            ('property', self.new_qos_spec.specs),
-            ('name', self.new_qos_spec.name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.new_qos_spec.specs.update(
-            {'consumer': self.new_qos_spec.consumer}
-        )
-        self.qos_mock.create.assert_called_with(
-            self.new_qos_spec.name, self.new_qos_spec.specs
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-
-class TestQosDelete(TestQos):
-    qos_specs = volume_fakes.create_qoses(count=2)
-
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock.get = volume_fakes.get_qoses(self.qos_specs)
-        # Get the command object to test
-        self.cmd = qos_specs.DeleteQos(self.app, None)
-
-    def test_qos_delete_with_id(self):
-        arglist = [self.qos_specs[0].id]
-        verifylist = [('qos_specs', [self.qos_specs[0].id])]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, False)
-        self.assertIsNone(result)
-
-    def test_qos_delete_with_name(self):
-        arglist = [self.qos_specs[0].name]
-        verifylist = [('qos_specs', [self.qos_specs[0].name])]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, False)
-        self.assertIsNone(result)
-
-    def test_qos_delete_with_force(self):
-        arglist = ['--force', self.qos_specs[0].id]
-        verifylist = [('force', True), ('qos_specs', [self.qos_specs[0].id])]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.delete.assert_called_with(self.qos_specs[0].id, True)
-        self.assertIsNone(result)
-
-    def test_delete_multiple_qoses(self):
-        arglist = []
-        for q in self.qos_specs:
-            arglist.append(q.id)
-        verifylist = [
-            ('qos_specs', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
-
-        calls = []
-        for q in self.qos_specs:
-            calls.append(call(q.id, False))
-        self.qos_mock.delete.assert_has_calls(calls)
-        self.assertIsNone(result)
-
-    def test_delete_multiple_qoses_with_exception(self):
-        arglist = [
-            self.qos_specs[0].id,
-            'unexist_qos',
-        ]
-        verifylist = [
-            ('qos_specs', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        find_mock_result = [self.qos_specs[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual(
-                    '1 of 2 QoS specifications failed to delete.', str(e)
-                )
-
-            find_mock.assert_any_call(self.qos_mock, self.qos_specs[0].id)
-            find_mock.assert_any_call(self.qos_mock, 'unexist_qos')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.qos_mock.delete.assert_called_once_with(
-                self.qos_specs[0].id, False
-            )
-
-
-class TestQosDisassociate(TestQos):
-    volume_type = volume_fakes.create_one_volume_type()
-    qos_spec = volume_fakes.create_one_qos()
-
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock.get.return_value = self.qos_spec
-        self.types_mock.get.return_value = self.volume_type
-        # Get the command object to test
-        self.cmd = qos_specs.DisassociateQos(self.app, None)
-
-    def test_qos_disassociate_with_volume_type(self):
-        arglist = [
-            '--volume-type',
-            self.volume_type.id,
-            self.qos_spec.id,
-        ]
-        verifylist = [
-            ('volume_type', self.volume_type.id),
-            ('qos_spec', self.qos_spec.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.disassociate.assert_called_with(
-            self.qos_spec.id, self.volume_type.id
-        )
-        self.assertIsNone(result)
-
-    def test_qos_disassociate_with_all_volume_types(self):
-        arglist = [
-            '--all',
-            self.qos_spec.id,
-        ]
-        verifylist = [('qos_spec', self.qos_spec.id)]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.disassociate_all.assert_called_with(self.qos_spec.id)
-        self.assertIsNone(result)
-
-
-class TestQosList(TestQos):
-    qos_specs = volume_fakes.create_qoses(count=2)
-    qos_association = volume_fakes.create_one_qos_association()
-
-    columns = (
-        'ID',
-        'Name',
-        'Consumer',
-        'Associations',
-        'Properties',
-    )
-    data = []
-    for q in qos_specs:
-        data.append(
-            (
-                q.id,
-                q.name,
-                q.consumer,
-                format_columns.ListColumn([qos_association.name]),
-                format_columns.DictColumn(q.specs),
-            )
-        )
-
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock.list.return_value = self.qos_specs
-        self.qos_mock.get_associations.return_value = [self.qos_association]
-
-        # Get the command object to test
-        self.cmd = qos_specs.ListQos(self.app, None)
-
-    def test_qos_list(self):
-        arglist = []
-        verifylist = []
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.qos_mock.list.assert_called_with()
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, list(data))
-
-    def test_qos_list_no_association(self):
-        self.qos_mock.reset_mock()
-        self.qos_mock.get_associations.side_effect = [
-            [self.qos_association],
-            exceptions.NotFound("NotFound"),
-        ]
-
-        arglist = []
-        verifylist = []
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.qos_mock.list.assert_called_with()
-
-        self.assertEqual(self.columns, columns)
-
-        ex_data = copy.deepcopy(self.data)
-        ex_data[1] = (
-            self.qos_specs[1].id,
-            self.qos_specs[1].name,
-            self.qos_specs[1].consumer,
-            format_columns.ListColumn(None),
-            format_columns.DictColumn(self.qos_specs[1].specs),
-        )
-        self.assertCountEqual(ex_data, list(data))
-
-
-class TestQosSet(TestQos):
-    qos_spec = volume_fakes.create_one_qos()
-
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock.get.return_value = self.qos_spec
-        # Get the command object to test
-        self.cmd = qos_specs.SetQos(self.app, None)
-
-    def test_qos_set_with_properties_with_id(self):
-        arglist = [
-            '--no-property',
-            '--property',
-            'a=b',
-            '--property',
-            'c=d',
-            self.qos_spec.id,
-        ]
-        new_property = {"a": "b", "c": "d"}
-        verifylist = [
-            ('no_property', True),
-            ('property', new_property),
-            ('qos_spec', self.qos_spec.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.unset_keys.assert_called_with(
-            self.qos_spec.id,
-            list(self.qos_spec.specs.keys()),
-        )
-        self.qos_mock.set_keys.assert_called_with(
-            self.qos_spec.id,
-            {"a": "b", "c": "d"},
-        )
-        self.assertIsNone(result)
-
-
-class TestQosShow(TestQos):
-    qos_spec = volume_fakes.create_one_qos()
-    qos_association = volume_fakes.create_one_qos_association()
-
-    def setUp(self):
-        super().setUp()
-        self.qos_mock.get.return_value = self.qos_spec
-        self.qos_mock.get_associations.return_value = [self.qos_association]
-        # Get the command object to test
-        self.cmd = qos_specs.ShowQos(self.app, None)
-
-    def test_qos_show(self):
-        arglist = [self.qos_spec.id]
-        verifylist = [('qos_spec', self.qos_spec.id)]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.qos_mock.get.assert_called_with(self.qos_spec.id)
-
-        collist = ('associations', 'consumer', 'id', 'name', 'properties')
-        self.assertEqual(collist, columns)
-        datalist = (
-            format_columns.ListColumn([self.qos_association.name]),
-            self.qos_spec.consumer,
-            self.qos_spec.id,
-            self.qos_spec.name,
-            format_columns.DictColumn(self.qos_spec.specs),
-        )
-        self.assertCountEqual(datalist, tuple(data))
-
-
-class TestQosUnset(TestQos):
-    qos_spec = volume_fakes.create_one_qos()
-
-    def setUp(self):
-        super().setUp()
-
-        self.qos_mock.get.return_value = self.qos_spec
-        # Get the command object to test
-        self.cmd = qos_specs.UnsetQos(self.app, None)
-
-    def test_qos_unset_with_properties(self):
-        arglist = [
-            '--property',
-            'iops',
-            '--property',
-            'foo',
-            self.qos_spec.id,
-        ]
-        verifylist = [
-            ('property', ['iops', 'foo']),
-            ('qos_spec', self.qos_spec.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.qos_mock.unset_keys.assert_called_with(
-            self.qos_spec.id, ['iops', 'foo']
-        )
-        self.assertIsNone(result)
-
-    def test_qos_unset_nothing(self):
-        arglist = [
-            self.qos_spec.id,
-        ]
-
-        verifylist = [
-            ('qos_spec', self.qos_spec.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.assertIsNone(result)
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/test_service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_service.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/test_service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_service.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,295 +0,0 @@
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-from osc_lib import exceptions
-
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import service
-
-
-class TestService(volume_fakes.TestVolumev1):
-    def setUp(self):
-        super().setUp()
-
-        # Get a shortcut to the ServiceManager Mock
-        self.service_mock = self.volume_client.services
-        self.service_mock.reset_mock()
-
-
-class TestServiceList(TestService):
-    # The service to be listed
-    services = volume_fakes.create_one_service()
-
-    def setUp(self):
-        super().setUp()
-
-        self.service_mock.list.return_value = [self.services]
-
-        # Get the command object to test
-        self.cmd = service.ListService(self.app, None)
-
-    def test_service_list(self):
-        arglist = [
-            '--host',
-            self.services.host,
-            '--service',
-            self.services.binary,
-        ]
-        verifylist = [
-            ('host', self.services.host),
-            ('service', self.services.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        expected_columns = [
-            'Binary',
-            'Host',
-            'Zone',
-            'Status',
-            'State',
-            'Updated At',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
-        datalist = (
-            (
-                self.services.binary,
-                self.services.host,
-                self.services.zone,
-                self.services.status,
-                self.services.state,
-                self.services.updated_at,
-            ),
-        )
-
-        # confirming if all expected values are present in the result.
-        self.assertEqual(datalist, tuple(data))
-
-        # checking if proper call was made to list services
-        self.service_mock.list.assert_called_with(
-            self.services.host,
-            self.services.binary,
-        )
-
-        # checking if prohibited columns are present in output
-        self.assertNotIn("Disabled Reason", columns)
-        self.assertNotIn(self.services.disabled_reason, tuple(data))
-
-    def test_service_list_with_long_option(self):
-        arglist = [
-            '--host',
-            self.services.host,
-            '--service',
-            self.services.binary,
-            '--long',
-        ]
-        verifylist = [
-            ('host', self.services.host),
-            ('service', self.services.binary),
-            ('long', True),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        expected_columns = [
-            'Binary',
-            'Host',
-            'Zone',
-            'Status',
-            'State',
-            'Updated At',
-            'Disabled Reason',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
-        datalist = (
-            (
-                self.services.binary,
-                self.services.host,
-                self.services.zone,
-                self.services.status,
-                self.services.state,
-                self.services.updated_at,
-                self.services.disabled_reason,
-            ),
-        )
-
-        # confirming if all expected values are present in the result.
-        self.assertEqual(datalist, tuple(data))
-
-        self.service_mock.list.assert_called_with(
-            self.services.host,
-            self.services.binary,
-        )
-
-
-class TestServiceSet(TestService):
-    service = volume_fakes.create_one_service()
-
-    def setUp(self):
-        super().setUp()
-
-        self.service_mock.enable.return_value = self.service
-        self.service_mock.disable.return_value = self.service
-        self.service_mock.disable_log_reason.return_value = self.service
-
-        self.cmd = service.SetService(self.app, None)
-
-    def test_service_set_nothing(self):
-        arglist = [
-            self.service.host,
-            self.service.binary,
-        ]
-        verifylist = [
-            ('host', self.service.host),
-            ('service', self.service.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
-
-        self.service_mock.enable.assert_not_called()
-        self.service_mock.disable.assert_not_called()
-        self.service_mock.disable_log_reason.assert_not_called()
-        self.assertIsNone(result)
-
-    def test_service_set_enable(self):
-        arglist = [
-            '--enable',
-            self.service.host,
-            self.service.binary,
-        ]
-        verifylist = [
-            ('enable', True),
-            ('host', self.service.host),
-            ('service', self.service.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.service_mock.enable.assert_called_with(
-            self.service.host, self.service.binary
-        )
-        self.service_mock.disable.assert_not_called()
-        self.service_mock.disable_log_reason.assert_not_called()
-        self.assertIsNone(result)
-
-    def test_service_set_disable(self):
-        arglist = [
-            '--disable',
-            self.service.host,
-            self.service.binary,
-        ]
-        verifylist = [
-            ('disable', True),
-            ('host', self.service.host),
-            ('service', self.service.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.service_mock.disable.assert_called_with(
-            self.service.host, self.service.binary
-        )
-        self.service_mock.enable.assert_not_called()
-        self.service_mock.disable_log_reason.assert_not_called()
-        self.assertIsNone(result)
-
-    def test_service_set_disable_with_reason(self):
-        reason = 'earthquake'
-        arglist = [
-            '--disable',
-            '--disable-reason',
-            reason,
-            self.service.host,
-            self.service.binary,
-        ]
-        verifylist = [
-            ('disable', True),
-            ('disable_reason', reason),
-            ('host', self.service.host),
-            ('service', self.service.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.service_mock.disable_log_reason.assert_called_with(
-            self.service.host, self.service.binary, reason
-        )
-        self.assertIsNone(result)
-
-    def test_service_set_only_with_disable_reason(self):
-        reason = 'earthquake'
-        arglist = [
-            '--disable-reason',
-            reason,
-            self.service.host,
-            self.service.binary,
-        ]
-        verifylist = [
-            ('disable_reason', reason),
-            ('host', self.service.host),
-            ('service', self.service.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail("CommandError should be raised.")
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                "Cannot specify option --disable-reason without "
-                "--disable specified.",
-                str(e),
-            )
-
-    def test_service_set_enable_with_disable_reason(self):
-        reason = 'earthquake'
-        arglist = [
-            '--enable',
-            '--disable-reason',
-            reason,
-            self.service.host,
-            self.service.binary,
-        ]
-        verifylist = [
-            ('enable', True),
-            ('disable_reason', reason),
-            ('host', self.service.host),
-            ('service', self.service.binary),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail("CommandError should be raised.")
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                "Cannot specify option --disable-reason without "
-                "--disable specified.",
-                str(e),
-            )
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/test_transfer_request.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_transfer_request.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/test_transfer_request.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_transfer_request.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,380 +0,0 @@
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-from unittest import mock
-from unittest.mock import call
-
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import volume_transfer_request
-
-
-class TestTransfer(volume_fakes.TestVolumev1):
-    def setUp(self):
-        super().setUp()
-
-        # Get a shortcut to the TransferManager Mock
-        self.transfer_mock = self.volume_client.transfers
-        self.transfer_mock.reset_mock()
-
-        # Get a shortcut to the VolumeManager Mock
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-
-
-class TestTransferAccept(TestTransfer):
-    columns = (
-        'id',
-        'name',
-        'volume_id',
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.volume_transfer = volume_fakes.create_one_transfer()
-        self.data = (
-            self.volume_transfer.id,
-            self.volume_transfer.name,
-            self.volume_transfer.volume_id,
-        )
-
-        self.transfer_mock.get.return_value = self.volume_transfer
-        self.transfer_mock.accept.return_value = self.volume_transfer
-
-        # Get the command object to test
-        self.cmd = volume_transfer_request.AcceptTransferRequest(
-            self.app, None
-        )
-
-    def test_transfer_accept(self):
-        arglist = [
-            '--auth-key',
-            'key_value',
-            self.volume_transfer.id,
-        ]
-        verifylist = [
-            ('transfer_request', self.volume_transfer.id),
-            ('auth_key', 'key_value'),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.transfer_mock.get.assert_called_once_with(
-            self.volume_transfer.id,
-        )
-        self.transfer_mock.accept.assert_called_once_with(
-            self.volume_transfer.id,
-            'key_value',
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
-
-    def test_transfer_accept_no_option(self):
-        arglist = [
-            self.volume_transfer.id,
-        ]
-        verifylist = [
-            ('transfer_request', self.volume_transfer.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args,
-        )
-
-
-class TestTransferCreate(TestTransfer):
-    volume = volume_fakes.create_one_volume()
-
-    columns = (
-        'auth_key',
-        'created_at',
-        'id',
-        'name',
-        'volume_id',
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.volume_transfer = volume_fakes.create_one_transfer(
-            attrs={
-                'volume_id': self.volume.id,
-                'auth_key': 'key',
-                'created_at': 'time',
-            },
-        )
-        self.data = (
-            self.volume_transfer.auth_key,
-            self.volume_transfer.created_at,
-            self.volume_transfer.id,
-            self.volume_transfer.name,
-            self.volume_transfer.volume_id,
-        )
-
-        self.transfer_mock.create.return_value = self.volume_transfer
-        self.volumes_mock.get.return_value = self.volume
-
-        # Get the command object to test
-        self.cmd = volume_transfer_request.CreateTransferRequest(
-            self.app, None
-        )
-
-    def test_transfer_create_without_name(self):
-        arglist = [
-            self.volume.id,
-        ]
-        verifylist = [
-            ('volume', self.volume.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.transfer_mock.create.assert_called_once_with(self.volume.id, None)
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
-
-    def test_transfer_create_with_name(self):
-        arglist = [
-            '--name',
-            self.volume_transfer.name,
-            self.volume.id,
-        ]
-        verifylist = [
-            ('name', self.volume_transfer.name),
-            ('volume', self.volume.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.transfer_mock.create.assert_called_once_with(
-            self.volume.id,
-            self.volume_transfer.name,
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
-
-
-class TestTransferDelete(TestTransfer):
-    volume_transfers = volume_fakes.create_transfers(count=2)
-
-    def setUp(self):
-        super().setUp()
-
-        self.transfer_mock.get = volume_fakes.get_transfers(
-            self.volume_transfers,
-        )
-        self.transfer_mock.delete.return_value = None
-
-        # Get the command object to mock
-        self.cmd = volume_transfer_request.DeleteTransferRequest(
-            self.app, None
-        )
-
-    def test_transfer_delete(self):
-        arglist = [self.volume_transfers[0].id]
-        verifylist = [("transfer_request", [self.volume_transfers[0].id])]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.transfer_mock.delete.assert_called_with(
-            self.volume_transfers[0].id
-        )
-        self.assertIsNone(result)
-
-    def test_delete_multiple_transfers(self):
-        arglist = []
-        for v in self.volume_transfers:
-            arglist.append(v.id)
-        verifylist = [
-            ('transfer_request', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
-
-        calls = []
-        for v in self.volume_transfers:
-            calls.append(call(v.id))
-        self.transfer_mock.delete.assert_has_calls(calls)
-        self.assertIsNone(result)
-
-    def test_delete_multiple_transfers_with_exception(self):
-        arglist = [
-            self.volume_transfers[0].id,
-            'unexist_transfer',
-        ]
-        verifylist = [
-            ('transfer_request', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        find_mock_result = [self.volume_transfers[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual(
-                    '1 of 2 volume transfer requests failed ' 'to delete',
-                    str(e),
-                )
-
-            find_mock.assert_any_call(
-                self.transfer_mock, self.volume_transfers[0].id
-            )
-            find_mock.assert_any_call(self.transfer_mock, 'unexist_transfer')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.transfer_mock.delete.assert_called_once_with(
-                self.volume_transfers[0].id,
-            )
-
-
-class TestTransferList(TestTransfer):
-    # The Transfers to be listed
-    volume_transfers = volume_fakes.create_one_transfer()
-
-    def setUp(self):
-        super().setUp()
-
-        self.transfer_mock.list.return_value = [self.volume_transfers]
-
-        # Get the command object to test
-        self.cmd = volume_transfer_request.ListTransferRequest(self.app, None)
-
-    def test_transfer_list_without_argument(self):
-        arglist = []
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        expected_columns = [
-            'ID',
-            'Name',
-            'Volume',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
-        datalist = (
-            (
-                self.volume_transfers.id,
-                self.volume_transfers.name,
-                self.volume_transfers.volume_id,
-            ),
-        )
-
-        # confirming if all expected values are present in the result.
-        self.assertEqual(datalist, tuple(data))
-
-        # checking if proper call was made to list volume_transfers
-        self.transfer_mock.list.assert_called_with(
-            detailed=True, search_opts={'all_tenants': 0}
-        )
-
-    def test_transfer_list_with_argument(self):
-        arglist = ["--all-projects"]
-        verifylist = [("all_projects", True)]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        expected_columns = [
-            'ID',
-            'Name',
-            'Volume',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
-        datalist = (
-            (
-                self.volume_transfers.id,
-                self.volume_transfers.name,
-                self.volume_transfers.volume_id,
-            ),
-        )
-
-        # confirming if all expected values are present in the result.
-        self.assertEqual(datalist, tuple(data))
-
-        # checking if proper call was made to list volume_transfers
-        self.transfer_mock.list.assert_called_with(
-            detailed=True, search_opts={'all_tenants': 1}
-        )
-
-
-class TestTransferShow(TestTransfer):
-    columns = (
-        'created_at',
-        'id',
-        'name',
-        'volume_id',
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.volume_transfer = volume_fakes.create_one_transfer(
-            attrs={'created_at': 'time'}
-        )
-        self.data = (
-            self.volume_transfer.created_at,
-            self.volume_transfer.id,
-            self.volume_transfer.name,
-            self.volume_transfer.volume_id,
-        )
-
-        self.transfer_mock.get.return_value = self.volume_transfer
-
-        # Get the command object to test
-        self.cmd = volume_transfer_request.ShowTransferRequest(self.app, None)
-
-    def test_transfer_show(self):
-        arglist = [
-            self.volume_transfer.id,
-        ]
-        verifylist = [
-            ('transfer_request', self.volume_transfer.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.transfer_mock.get.assert_called_once_with(self.volume_transfer.id)
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/test_type.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_type.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/test_type.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_type.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,633 +0,0 @@
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-from unittest import mock
-from unittest.mock import call
-
-from osc_lib.cli import format_columns
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit import utils as tests_utils
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import volume_type
-
-
-class TestType(volume_fakes.TestVolumev1):
-    def setUp(self):
-        super().setUp()
-
-        self.types_mock = self.volume_client.volume_types
-        self.types_mock.reset_mock()
-
-        self.encryption_types_mock = self.volume_client.volume_encryption_types
-        self.encryption_types_mock.reset_mock()
-
-
-class TestTypeCreate(TestType):
-    columns = (
-        'description',
-        'id',
-        'is_public',
-        'name',
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.new_volume_type = volume_fakes.create_one_volume_type(
-            methods={'set_keys': {'myprop': 'myvalue'}},
-        )
-        self.data = (
-            self.new_volume_type.description,
-            self.new_volume_type.id,
-            True,
-            self.new_volume_type.name,
-        )
-
-        self.types_mock.create.return_value = self.new_volume_type
-        # Get the command object to test
-        self.cmd = volume_type.CreateVolumeType(self.app, None)
-
-    def test_type_create(self):
-        arglist = [
-            self.new_volume_type.name,
-        ]
-        verifylist = [
-            ("name", self.new_volume_type.name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.types_mock.create.assert_called_with(
-            self.new_volume_type.name,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, data)
-
-    def test_type_create_with_encryption(self):
-        encryption_info = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': '128',
-            'control_location': 'front-end',
-        }
-        encryption_type = volume_fakes.create_one_encryption_volume_type(
-            attrs=encryption_info,
-        )
-        self.new_volume_type = volume_fakes.create_one_volume_type(
-            attrs={'encryption': encryption_info},
-        )
-        self.types_mock.create.return_value = self.new_volume_type
-        self.encryption_types_mock.create.return_value = encryption_type
-        encryption_columns = (
-            'description',
-            'encryption',
-            'id',
-            'is_public',
-            'name',
-        )
-        encryption_data = (
-            self.new_volume_type.description,
-            format_columns.DictColumn(encryption_info),
-            self.new_volume_type.id,
-            True,
-            self.new_volume_type.name,
-        )
-        arglist = [
-            '--encryption-provider',
-            'LuksEncryptor',
-            '--encryption-cipher',
-            'aes-xts-plain64',
-            '--encryption-key-size',
-            '128',
-            '--encryption-control-location',
-            'front-end',
-            self.new_volume_type.name,
-        ]
-        verifylist = [
-            ('encryption_provider', 'LuksEncryptor'),
-            ('encryption_cipher', 'aes-xts-plain64'),
-            ('encryption_key_size', 128),
-            ('encryption_control_location', 'front-end'),
-            ('name', self.new_volume_type.name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.types_mock.create.assert_called_with(
-            self.new_volume_type.name,
-        )
-        body = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': 128,
-            'control_location': 'front-end',
-        }
-        self.encryption_types_mock.create.assert_called_with(
-            self.new_volume_type,
-            body,
-        )
-        self.assertEqual(encryption_columns, columns)
-        self.assertCountEqual(encryption_data, data)
-
-
-class TestTypeDelete(TestType):
-    volume_types = volume_fakes.create_volume_types(count=2)
-
-    def setUp(self):
-        super().setUp()
-
-        self.types_mock.get = volume_fakes.get_volume_types(self.volume_types)
-        self.types_mock.delete.return_value = None
-
-        # Get the command object to mock
-        self.cmd = volume_type.DeleteVolumeType(self.app, None)
-
-    def test_type_delete(self):
-        arglist = [self.volume_types[0].id]
-        verifylist = [("volume_types", [self.volume_types[0].id])]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.types_mock.delete.assert_called_with(self.volume_types[0])
-        self.assertIsNone(result)
-
-    def test_delete_multiple_types(self):
-        arglist = []
-        for t in self.volume_types:
-            arglist.append(t.id)
-        verifylist = [
-            ('volume_types', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
-
-        calls = []
-        for t in self.volume_types:
-            calls.append(call(t))
-        self.types_mock.delete.assert_has_calls(calls)
-        self.assertIsNone(result)
-
-    def test_delete_multiple_types_with_exception(self):
-        arglist = [
-            self.volume_types[0].id,
-            'unexist_type',
-        ]
-        verifylist = [
-            ('volume_types', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        find_mock_result = [self.volume_types[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual(
-                    '1 of 2 volume types failed to delete.', str(e)
-                )
-
-            find_mock.assert_any_call(self.types_mock, self.volume_types[0].id)
-            find_mock.assert_any_call(self.types_mock, 'unexist_type')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.types_mock.delete.assert_called_once_with(
-                self.volume_types[0]
-            )
-
-
-class TestTypeList(TestType):
-    volume_types = volume_fakes.create_volume_types()
-
-    columns = [
-        "ID",
-        "Name",
-        "Is Public",
-    ]
-    columns_long = ["ID", "Name", "Is Public", "Properties"]
-
-    data = []
-    for t in volume_types:
-        data.append(
-            (
-                t.id,
-                t.name,
-                t.is_public,
-            )
-        )
-    data_long = []
-    for t in volume_types:
-        data_long.append(
-            (
-                t.id,
-                t.name,
-                t.is_public,
-                format_columns.DictColumn(t.extra_specs),
-            )
-        )
-
-    def setUp(self):
-        super().setUp()
-
-        self.types_mock.list.return_value = self.volume_types
-        self.encryption_types_mock.create.return_value = None
-        self.encryption_types_mock.update.return_value = None
-        # get the command to test
-        self.cmd = volume_type.ListVolumeType(self.app, None)
-
-    def test_type_list_without_options(self):
-        arglist = []
-        verifylist = [
-            ("long", False),
-            ("encryption_type", False),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.types_mock.list.assert_called_once_with()
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, list(data))
-
-    def test_type_list_with_options(self):
-        arglist = [
-            "--long",
-        ]
-        verifylist = [
-            ("long", True),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.types_mock.list.assert_called_once_with()
-        self.assertEqual(self.columns_long, columns)
-        self.assertCountEqual(self.data_long, list(data))
-
-    def test_type_list_with_encryption(self):
-        encryption_type = volume_fakes.create_one_encryption_volume_type(
-            attrs={'volume_type_id': self.volume_types[0].id},
-        )
-        encryption_info = {
-            'provider': 'LuksEncryptor',
-            'cipher': None,
-            'key_size': None,
-            'control_location': 'front-end',
-        }
-        encryption_columns = self.columns + [
-            "Encryption",
-        ]
-        encryption_data = []
-        encryption_data.append(
-            (
-                self.volume_types[0].id,
-                self.volume_types[0].name,
-                self.volume_types[0].is_public,
-                volume_type.EncryptionInfoColumn(
-                    self.volume_types[0].id,
-                    {self.volume_types[0].id: encryption_info},
-                ),
-            )
-        )
-        encryption_data.append(
-            (
-                self.volume_types[1].id,
-                self.volume_types[1].name,
-                self.volume_types[1].is_public,
-                volume_type.EncryptionInfoColumn(self.volume_types[1].id, {}),
-            )
-        )
-
-        self.encryption_types_mock.list.return_value = [encryption_type]
-        arglist = [
-            "--encryption-type",
-        ]
-        verifylist = [
-            ("encryption_type", True),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.encryption_types_mock.list.assert_called_once_with()
-        self.types_mock.list.assert_called_once_with()
-        self.assertEqual(encryption_columns, columns)
-        self.assertCountEqual(encryption_data, list(data))
-
-
-class TestTypeSet(TestType):
-    volume_type = volume_fakes.create_one_volume_type(
-        methods={'set_keys': None},
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.types_mock.get.return_value = self.volume_type
-
-        # Get the command object to test
-        self.cmd = volume_type.SetVolumeType(self.app, None)
-
-    def test_type_set_nothing(self):
-        arglist = [
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('volume_type', self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.assertIsNone(result)
-
-    def test_type_set_property(self):
-        arglist = [
-            '--property',
-            'myprop=myvalue',
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('property', {'myprop': 'myvalue'}),
-            ('volume_type', self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.volume_type.set_keys.assert_called_once_with(
-            {'myprop': 'myvalue'}
-        )
-        self.assertIsNone(result)
-
-    def test_type_set_new_encryption(self):
-        arglist = [
-            '--encryption-provider',
-            'LuksEncryptor',
-            '--encryption-cipher',
-            'aes-xts-plain64',
-            '--encryption-key-size',
-            '128',
-            '--encryption-control-location',
-            'front-end',
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('encryption_provider', 'LuksEncryptor'),
-            ('encryption_cipher', 'aes-xts-plain64'),
-            ('encryption_key_size', 128),
-            ('encryption_control_location', 'front-end'),
-            ('volume_type', self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        body = {
-            'provider': 'LuksEncryptor',
-            'cipher': 'aes-xts-plain64',
-            'key_size': 128,
-            'control_location': 'front-end',
-        }
-        self.encryption_types_mock.create.assert_called_with(
-            self.volume_type,
-            body,
-        )
-        self.assertIsNone(result)
-
-    def test_type_set_new_encryption_without_provider(self):
-        arglist = [
-            '--encryption-cipher',
-            'aes-xts-plain64',
-            '--encryption-key-size',
-            '128',
-            '--encryption-control-location',
-            'front-end',
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('encryption_cipher', 'aes-xts-plain64'),
-            ('encryption_key_size', 128),
-            ('encryption_control_location', 'front-end'),
-            ('volume_type', self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail('CommandError should be raised.')
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                "Command Failed: One or more of" " the operations failed",
-                str(e),
-            )
-        self.encryption_types_mock.create.assert_not_called()
-        self.encryption_types_mock.update.assert_not_called()
-
-
-class TestTypeShow(TestType):
-    columns = (
-        'description',
-        'id',
-        'is_public',
-        'name',
-        'properties',
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.volume_type = volume_fakes.create_one_volume_type()
-        self.data = (
-            self.volume_type.description,
-            self.volume_type.id,
-            True,
-            self.volume_type.name,
-            format_columns.DictColumn(self.volume_type.extra_specs),
-        )
-
-        self.types_mock.get.return_value = self.volume_type
-
-        # Get the command object to test
-        self.cmd = volume_type.ShowVolumeType(self.app, None)
-
-    def test_type_show(self):
-        arglist = [self.volume_type.id]
-        verifylist = [
-            ("volume_type", self.volume_type.id),
-            ("encryption_type", False),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.types_mock.get.assert_called_with(self.volume_type.id)
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, data)
-
-    def test_type_show_with_encryption(self):
-        encryption_type = volume_fakes.create_one_encryption_volume_type()
-        encryption_info = {
-            'provider': 'LuksEncryptor',
-            'cipher': None,
-            'key_size': None,
-            'control_location': 'front-end',
-        }
-        self.volume_type = volume_fakes.create_one_volume_type(
-            attrs={'encryption': encryption_info},
-        )
-        self.types_mock.get.return_value = self.volume_type
-        self.encryption_types_mock.get.return_value = encryption_type
-        encryption_columns = (
-            'description',
-            'encryption',
-            'id',
-            'is_public',
-            'name',
-            'properties',
-        )
-        encryption_data = (
-            self.volume_type.description,
-            format_columns.DictColumn(encryption_info),
-            self.volume_type.id,
-            True,
-            self.volume_type.name,
-            format_columns.DictColumn(self.volume_type.extra_specs),
-        )
-        arglist = ['--encryption-type', self.volume_type.id]
-        verifylist = [
-            ('encryption_type', True),
-            ("volume_type", self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.types_mock.get.assert_called_with(self.volume_type.id)
-        self.encryption_types_mock.get.assert_called_with(self.volume_type.id)
-        self.assertEqual(encryption_columns, columns)
-        self.assertCountEqual(encryption_data, data)
-
-
-class TestTypeUnset(TestType):
-    volume_type = volume_fakes.create_one_volume_type(
-        methods={'unset_keys': None},
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.types_mock.get.return_value = self.volume_type
-
-        # Get the command object to test
-        self.cmd = volume_type.UnsetVolumeType(self.app, None)
-
-    def test_type_unset_property(self):
-        arglist = [
-            '--property',
-            'property',
-            '--property',
-            'multi_property',
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('encryption_type', False),
-            ('property', ['property', 'multi_property']),
-            ('volume_type', self.volume_type.id),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.volume_type.unset_keys.assert_called_once_with(
-            ['property', 'multi_property']
-        )
-        self.encryption_types_mock.delete.assert_not_called()
-        self.assertIsNone(result)
-
-    def test_type_unset_failed_with_missing_volume_type_argument(self):
-        arglist = [
-            '--property',
-            'property',
-            '--property',
-            'multi_property',
-        ]
-        verifylist = [
-            ('property', ['property', 'multi_property']),
-        ]
-
-        self.assertRaises(
-            tests_utils.ParserException,
-            self.check_parser,
-            self.cmd,
-            arglist,
-            verifylist,
-        )
-
-    def test_type_unset_nothing(self):
-        arglist = [
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('volume_type', self.volume_type.id),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.assertIsNone(result)
-
-    def test_type_unset_encryption_type(self):
-        arglist = [
-            '--encryption-type',
-            self.volume_type.id,
-        ]
-        verifylist = [
-            ('encryption_type', True),
-            ('volume_type', self.volume_type.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.encryption_types_mock.delete.assert_called_with(self.volume_type)
-        self.assertIsNone(result)
-
-
-class TestColumns(TestType):
-    def test_encryption_info_column_with_info(self):
-        fake_volume_type = volume_fakes.create_one_volume_type()
-        type_id = fake_volume_type.id
-
-        encryption_info = {
-            'provider': 'LuksEncryptor',
-            'cipher': None,
-            'key_size': None,
-            'control_location': 'front-end',
-        }
-        col = volume_type.EncryptionInfoColumn(
-            type_id, {type_id: encryption_info}
-        )
-        self.assertEqual(
-            utils.format_dict(encryption_info), col.human_readable()
-        )
-        self.assertEqual(encryption_info, col.machine_readable())
-
-    def test_encryption_info_column_without_info(self):
-        fake_volume_type = volume_fakes.create_one_volume_type()
-        type_id = fake_volume_type.id
-
-        col = volume_type.EncryptionInfoColumn(type_id, {})
-        self.assertEqual('-', col.human_readable())
-        self.assertIsNone(col.machine_readable())
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/test_volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_volume.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/test_volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_volume.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,1447 +0,0 @@
-#   Copyright 2013 Nebula Inc.
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-
-from unittest import mock
-from unittest.mock import call
-
-from osc_lib.cli import format_columns
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
-from openstackclient.tests.unit.image.v1 import fakes as image_fakes
-from openstackclient.tests.unit import utils as test_utils
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import volume
-
-
-class TestVolume(volume_fakes.TestVolumev1):
-    def setUp(self):
-        super().setUp()
-
-        # Get a shortcut to the VolumeManager Mock
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-
-        # Get a shortcut to the TenantManager Mock
-        self.projects_mock = self.identity_client.tenants
-        self.projects_mock.reset_mock()
-
-        # Get a shortcut to the UserManager Mock
-        self.users_mock = self.identity_client.users
-        self.users_mock.reset_mock()
-
-    def setup_volumes_mock(self, count):
-        volumes = volume_fakes.create_volumes(count=count)
-
-        self.volumes_mock.get = volume_fakes.get_volumes(volumes, 0)
-        return volumes
-
-
-class TestVolumeCreate(TestVolume):
-    project = identity_fakes.FakeProject.create_one_project()
-    user = identity_fakes.FakeUser.create_one_user()
-
-    columns = (
-        'attachments',
-        'availability_zone',
-        'bootable',
-        'created_at',
-        'display_description',
-        'id',
-        'name',
-        'properties',
-        'size',
-        'snapshot_id',
-        'status',
-        'type',
-    )
-
-    def setUp(self):
-        super().setUp()
-        self.new_volume = volume_fakes.create_one_volume()
-        self.datalist = (
-            self.new_volume.attachments,
-            self.new_volume.availability_zone,
-            self.new_volume.bootable,
-            self.new_volume.created_at,
-            self.new_volume.display_description,
-            self.new_volume.id,
-            self.new_volume.display_name,
-            format_columns.DictColumn(self.new_volume.metadata),
-            self.new_volume.size,
-            self.new_volume.snapshot_id,
-            self.new_volume.status,
-            self.new_volume.volume_type,
-        )
-        self.volumes_mock.create.return_value = self.new_volume
-
-        # Get the command object to test
-        self.cmd = volume.CreateVolume(self.app, None)
-
-    def test_volume_create_min_options(self):
-        arglist = [
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_options(self):
-        arglist = [
-            '--size',
-            str(self.new_volume.size),
-            '--description',
-            self.new_volume.display_description,
-            '--type',
-            self.new_volume.volume_type,
-            '--availability-zone',
-            self.new_volume.availability_zone,
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('size', self.new_volume.size),
-            ('description', self.new_volume.display_description),
-            ('type', self.new_volume.volume_type),
-            ('availability_zone', self.new_volume.availability_zone),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            self.new_volume.display_description,
-            self.new_volume.volume_type,
-            None,
-            None,
-            self.new_volume.availability_zone,
-            None,
-            None,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_user_project_id(self):
-        # Return a project
-        self.projects_mock.get.return_value = self.project
-        # Return a user
-        self.users_mock.get.return_value = self.user
-
-        arglist = [
-            '--size',
-            str(self.new_volume.size),
-            '--project',
-            self.project.id,
-            '--user',
-            self.user.id,
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('size', self.new_volume.size),
-            ('project', self.project.id),
-            ('user', self.user.id),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            self.user.id,
-            self.project.id,
-            None,
-            None,
-            None,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_user_project_name(self):
-        # Return a project
-        self.projects_mock.get.return_value = self.project
-        # Return a user
-        self.users_mock.get.return_value = self.user
-
-        arglist = [
-            '--size',
-            str(self.new_volume.size),
-            '--project',
-            self.project.name,
-            '--user',
-            self.user.name,
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('size', self.new_volume.size),
-            ('project', self.project.name),
-            ('user', self.user.name),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            self.user.id,
-            self.project.id,
-            None,
-            None,
-            None,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_properties(self):
-        arglist = [
-            '--property',
-            'Alpha=a',
-            '--property',
-            'Beta=b',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('property', {'Alpha': 'a', 'Beta': 'b'}),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            {'Alpha': 'a', 'Beta': 'b'},
-            None,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_image_id(self):
-        image = image_fakes.create_one_image()
-        self.image_client.find_image.return_value = image
-
-        arglist = [
-            '--image',
-            image.id,
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('image', image.id),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            image.id,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_image_name(self):
-        image = image_fakes.create_one_image()
-        self.image_client.find_image.return_value = image
-
-        arglist = [
-            '--image',
-            image.name,
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('image', image.name),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns a two-part tuple with a tuple of column names and a tuple of
-        # data to be shown.
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # VolumeManager.create(size, snapshot_id=, source_volid=,
-        #                      display_name=, display_description=,
-        #                      volume_type=, user_id=,
-        #                      project_id=, availability_zone=,
-        #                      metadata=, imageRef=)
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            image.id,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_with_source(self):
-        self.volumes_mock.get.return_value = self.new_volume
-        arglist = [
-            '--source',
-            self.new_volume.id,
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('source', self.new_volume.id),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.create.assert_called_with(
-            None,
-            None,
-            self.new_volume.id,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    @mock.patch.object(utils, 'wait_for_status', return_value=True)
-    def test_volume_create_with_bootable_and_readonly(self, mock_wait):
-        arglist = [
-            '--bootable',
-            '--read-only',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('bootable', True),
-            ('non_bootable', False),
-            ('read_only', True),
-            ('read_write', False),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-        self.volumes_mock.set_bootable.assert_called_with(
-            self.new_volume.id, True
-        )
-        self.volumes_mock.update_readonly_flag.assert_called_with(
-            self.new_volume.id, True
-        )
-
-    @mock.patch.object(utils, 'wait_for_status', return_value=True)
-    def test_volume_create_with_nonbootable_and_readwrite(self, mock_wait):
-        arglist = [
-            '--non-bootable',
-            '--read-write',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('bootable', False),
-            ('non_bootable', True),
-            ('read_only', False),
-            ('read_write', True),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-        self.volumes_mock.set_bootable.assert_called_with(
-            self.new_volume.id, False
-        )
-        self.volumes_mock.update_readonly_flag.assert_called_with(
-            self.new_volume.id, False
-        )
-
-    @mock.patch.object(volume.LOG, 'error')
-    @mock.patch.object(utils, 'wait_for_status', return_value=True)
-    def test_volume_create_with_bootable_and_readonly_fail(
-        self, mock_wait, mock_error
-    ):
-        self.volumes_mock.set_bootable.side_effect = exceptions.CommandError()
-
-        self.volumes_mock.update_readonly_flag.side_effect = (
-            exceptions.CommandError()
-        )
-
-        arglist = [
-            '--bootable',
-            '--read-only',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('bootable', True),
-            ('non_bootable', False),
-            ('read_only', True),
-            ('read_write', False),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-
-        self.assertEqual(2, mock_error.call_count)
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-        self.volumes_mock.set_bootable.assert_called_with(
-            self.new_volume.id, True
-        )
-        self.volumes_mock.update_readonly_flag.assert_called_with(
-            self.new_volume.id, True
-        )
-
-    @mock.patch.object(volume.LOG, 'error')
-    @mock.patch.object(utils, 'wait_for_status', return_value=False)
-    def test_volume_create_non_available_with_readonly(
-        self, mock_wait, mock_error
-    ):
-        arglist = [
-            '--non-bootable',
-            '--read-only',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('bootable', False),
-            ('non_bootable', True),
-            ('read_only', True),
-            ('read_write', False),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-
-        self.assertEqual(2, mock_error.call_count)
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_create_without_size(self):
-        arglist = [
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        self.assertRaises(
-            exceptions.CommandError, self.cmd.take_action, parsed_args
-        )
-
-    def test_volume_create_with_multi_source(self):
-        arglist = [
-            '--image',
-            'source_image',
-            '--source',
-            'source_volume',
-            '--snapshot',
-            'source_snapshot',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('image', 'source_image'),
-            ('source', 'source_volume'),
-            ('snapshot', 'source_snapshot'),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-
-        self.assertRaises(
-            test_utils.ParserException,
-            self.check_parser,
-            self.cmd,
-            arglist,
-            verifylist,
-        )
-
-    def test_volume_create_backward_compatibility(self):
-        arglist = [
-            '-c',
-            'display_name',
-            '--size',
-            str(self.new_volume.size),
-            self.new_volume.display_name,
-        ]
-        verifylist = [
-            ('columns', ['display_name']),
-            ('size', self.new_volume.size),
-            ('name', self.new_volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.create.assert_called_with(
-            self.new_volume.size,
-            None,
-            None,
-            self.new_volume.display_name,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-            None,
-        )
-        self.assertIn('display_name', columns)
-        self.assertNotIn('name', columns)
-        self.assertIn(self.new_volume.display_name, data)
-
-
-class TestVolumeDelete(TestVolume):
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock.delete.return_value = None
-
-        # Get the command object to mock
-        self.cmd = volume.DeleteVolume(self.app, None)
-
-    def test_volume_delete_one_volume(self):
-        volumes = self.setup_volumes_mock(count=1)
-
-        arglist = [volumes[0].id]
-        verifylist = [
-            ("force", False),
-            ("volumes", [volumes[0].id]),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.delete.assert_called_once_with(volumes[0].id)
-        self.assertIsNone(result)
-
-    def test_volume_delete_multi_volumes(self):
-        volumes = self.setup_volumes_mock(count=3)
-
-        arglist = [v.id for v in volumes]
-        verifylist = [
-            ('force', False),
-            ('volumes', arglist),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        calls = [call(v.id) for v in volumes]
-        self.volumes_mock.delete.assert_has_calls(calls)
-        self.assertIsNone(result)
-
-    def test_volume_delete_multi_volumes_with_exception(self):
-        volumes = self.setup_volumes_mock(count=2)
-
-        arglist = [
-            volumes[0].id,
-            'unexist_volume',
-        ]
-        verifylist = [
-            ('force', False),
-            ('volumes', arglist),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        find_mock_result = [volumes[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual('1 of 2 volumes failed to delete.', str(e))
-
-            find_mock.assert_any_call(self.volumes_mock, volumes[0].id)
-            find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.volumes_mock.delete.assert_called_once_with(volumes[0].id)
-
-    def test_volume_delete_with_force(self):
-        volumes = self.setup_volumes_mock(count=1)
-
-        arglist = [
-            '--force',
-            volumes[0].id,
-        ]
-        verifylist = [
-            ('force', True),
-            ('volumes', [volumes[0].id]),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.force_delete.assert_called_once_with(volumes[0].id)
-        self.assertIsNone(result)
-
-
-class TestVolumeList(TestVolume):
-    _volume = volume_fakes.create_one_volume()
-    columns = (
-        'ID',
-        'Name',
-        'Status',
-        'Size',
-        'Attached to',
-    )
-    datalist = (
-        (
-            _volume.id,
-            _volume.display_name,
-            _volume.status,
-            _volume.size,
-            volume.AttachmentsColumn(_volume.attachments),
-        ),
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock.list.return_value = [self._volume]
-
-        # Get the command object to test
-        self.cmd = volume.ListVolume(self.app, None)
-
-    def test_volume_list_no_options(self):
-        arglist = []
-        verifylist = [
-            ('long', False),
-            ('all_projects', False),
-            ('name', None),
-            ('status', None),
-            ('limit', None),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, tuple(data))
-
-    def test_volume_list_name(self):
-        arglist = [
-            '--name',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('long', False),
-            ('all_projects', False),
-            ('name', self._volume.display_name),
-            ('status', None),
-            ('limit', None),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.assertEqual(self.columns, tuple(columns))
-        self.assertCountEqual(self.datalist, tuple(data))
-
-    def test_volume_list_status(self):
-        arglist = [
-            '--status',
-            self._volume.status,
-        ]
-        verifylist = [
-            ('long', False),
-            ('all_projects', False),
-            ('name', None),
-            ('status', self._volume.status),
-            ('limit', None),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.assertEqual(self.columns, tuple(columns))
-        self.assertCountEqual(self.datalist, tuple(data))
-
-    def test_volume_list_all_projects(self):
-        arglist = [
-            '--all-projects',
-        ]
-        verifylist = [
-            ('long', False),
-            ('all_projects', True),
-            ('name', None),
-            ('status', None),
-            ('limit', None),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.assertEqual(self.columns, tuple(columns))
-        self.assertCountEqual(self.datalist, tuple(data))
-
-    def test_volume_list_long(self):
-        arglist = [
-            '--long',
-        ]
-        verifylist = [
-            ('long', True),
-            ('all_projects', False),
-            ('name', None),
-            ('status', None),
-            ('limit', None),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        collist = (
-            'ID',
-            'Name',
-            'Status',
-            'Size',
-            'Type',
-            'Bootable',
-            'Attached to',
-            'Properties',
-        )
-        self.assertEqual(collist, columns)
-
-        datalist = (
-            (
-                self._volume.id,
-                self._volume.display_name,
-                self._volume.status,
-                self._volume.size,
-                self._volume.volume_type,
-                self._volume.bootable,
-                volume.AttachmentsColumn(self._volume.attachments),
-                format_columns.DictColumn(self._volume.metadata),
-            ),
-        )
-        self.assertCountEqual(datalist, tuple(data))
-
-    def test_volume_list_with_limit_and_offset(self):
-        arglist = [
-            '--limit',
-            '2',
-            '--offset',
-            '5',
-        ]
-        verifylist = [
-            ('long', False),
-            ('all_projects', False),
-            ('name', None),
-            ('status', None),
-            ('limit', 2),
-            ('offset', 5),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.list.assert_called_once_with(
-            limit=2,
-            search_opts={
-                'offset': 5,
-                'status': None,
-                'display_name': None,
-                'all_tenants': False,
-            },
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, tuple(data))
-
-    def test_volume_list_negative_limit(self):
-        arglist = [
-            "--limit",
-            "-2",
-        ]
-        verifylist = [
-            ("limit", -2),
-        ]
-        self.assertRaises(
-            test_utils.ParserException,
-            self.check_parser,
-            self.cmd,
-            arglist,
-            verifylist,
-        )
-
-    def test_volume_list_backward_compatibility(self):
-        arglist = [
-            '-c',
-            'Display Name',
-        ]
-        verifylist = [
-            ('columns', ['Display Name']),
-            ('long', False),
-            ('all_projects', False),
-            ('name', None),
-            ('status', None),
-            ('limit', None),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.assertIn('Display Name', columns)
-        self.assertNotIn('Name', columns)
-        for each_volume in data:
-            self.assertIn(self._volume.display_name, each_volume)
-
-
-class TestVolumeMigrate(TestVolume):
-    _volume = volume_fakes.create_one_volume()
-
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock.get.return_value = self._volume
-        self.volumes_mock.migrate_volume.return_value = None
-        # Get the command object to test
-        self.cmd = volume.MigrateVolume(self.app, None)
-
-    def test_volume_migrate(self):
-        arglist = [
-            "--host",
-            "host@backend-name#pool",
-            self._volume.id,
-        ]
-        verifylist = [
-            ("force_host_copy", False),
-            ("host", "host@backend-name#pool"),
-            ("volume", self._volume.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.volumes_mock.get.assert_called_once_with(self._volume.id)
-        self.volumes_mock.migrate_volume.assert_called_once_with(
-            self._volume.id, "host@backend-name#pool", False
-        )
-        self.assertIsNone(result)
-
-    def test_volume_migrate_with_option(self):
-        arglist = [
-            "--force-host-copy",
-            "--host",
-            "host@backend-name#pool",
-            self._volume.id,
-        ]
-        verifylist = [
-            ("force_host_copy", True),
-            ("host", "host@backend-name#pool"),
-            ("volume", self._volume.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.volumes_mock.get.assert_called_once_with(self._volume.id)
-        self.volumes_mock.migrate_volume.assert_called_once_with(
-            self._volume.id, "host@backend-name#pool", True
-        )
-        self.assertIsNone(result)
-
-    def test_volume_migrate_without_host(self):
-        arglist = [
-            self._volume.id,
-        ]
-        verifylist = [
-            ("force_host_copy", False),
-            ("volume", self._volume.id),
-        ]
-
-        self.assertRaises(
-            test_utils.ParserException,
-            self.check_parser,
-            self.cmd,
-            arglist,
-            verifylist,
-        )
-
-
-class TestVolumeSet(TestVolume):
-    _volume = volume_fakes.create_one_volume()
-
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock.get.return_value = self._volume
-
-        self.volumes_mock.update.return_value = self._volume
-        # Get the command object to test
-        self.cmd = volume.SetVolume(self.app, None)
-
-    def test_volume_set_no_options(self):
-        arglist = [
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('name', None),
-            ('description', None),
-            ('size', None),
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.assertIsNone(result)
-
-    def test_volume_set_name(self):
-        arglist = [
-            '--name',
-            'qwerty',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('name', 'qwerty'),
-            ('description', None),
-            ('size', None),
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'display_name': 'qwerty',
-        }
-        self.volumes_mock.update.assert_called_with(self._volume.id, **kwargs)
-        self.assertIsNone(result)
-
-    def test_volume_set_description(self):
-        arglist = [
-            '--description',
-            'new desc',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('name', None),
-            ('description', 'new desc'),
-            ('size', None),
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'display_description': 'new desc',
-        }
-        self.volumes_mock.update.assert_called_with(self._volume.id, **kwargs)
-        self.assertIsNone(result)
-
-    def test_volume_set_size(self):
-        arglist = [
-            '--size',
-            '130',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('name', None),
-            ('description', None),
-            ('size', 130),
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        size = 130
-        self.volumes_mock.extend.assert_called_with(self._volume.id, size)
-        self.assertIsNone(result)
-
-    def test_volume_set_size_smaller(self):
-        self._volume.status = 'available'
-        arglist = [
-            '--size',
-            '1',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('name', None),
-            ('description', None),
-            ('size', 1),
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        self.assertRaises(
-            exceptions.CommandError, self.cmd.take_action, parsed_args
-        )
-
-    def test_volume_set_size_not_available(self):
-        self._volume.status = 'error'
-        arglist = [
-            '--size',
-            '130',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('name', None),
-            ('description', None),
-            ('size', 130),
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        self.assertRaises(
-            exceptions.CommandError, self.cmd.take_action, parsed_args
-        )
-
-    def test_volume_set_property(self):
-        arglist = [
-            '--no-property',
-            '--property',
-            'myprop=myvalue',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('read_only', False),
-            ('read_write', False),
-            ('name', None),
-            ('description', None),
-            ('size', None),
-            ('no_property', True),
-            ('property', {'myprop': 'myvalue'}),
-            ('volume', self._volume.display_name),
-            ('bootable', False),
-            ('non_bootable', False),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        metadata = {'myprop': 'myvalue'}
-        self.volumes_mock.set_metadata.assert_called_with(
-            self._volume.id, metadata
-        )
-        self.volumes_mock.delete_metadata.assert_called_with(
-            self._volume.id, self._volume.metadata.keys()
-        )
-        self.volumes_mock.update_readonly_flag.assert_not_called()
-        self.assertIsNone(result)
-
-    def test_volume_set_bootable(self):
-        arglist = [
-            ['--bootable', self._volume.id],
-            ['--non-bootable', self._volume.id],
-        ]
-        verifylist = [
-            [
-                ('bootable', True),
-                ('non_bootable', False),
-                ('volume', self._volume.id),
-            ],
-            [
-                ('bootable', False),
-                ('non_bootable', True),
-                ('volume', self._volume.id),
-            ],
-        ]
-        for index in range(len(arglist)):
-            parsed_args = self.check_parser(
-                self.cmd, arglist[index], verifylist[index]
-            )
-
-            self.cmd.take_action(parsed_args)
-            self.volumes_mock.set_bootable.assert_called_with(
-                self._volume.id, verifylist[index][0][1]
-            )
-
-    def test_volume_set_readonly(self):
-        arglist = ['--read-only', self._volume.id]
-        verifylist = [
-            ('read_only', True),
-            ('read_write', False),
-            ('volume', self._volume.id),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.volumes_mock.update_readonly_flag.assert_called_once_with(
-            self._volume.id, True
-        )
-        self.assertIsNone(result)
-
-    def test_volume_set_read_write(self):
-        arglist = ['--read-write', self._volume.id]
-        verifylist = [
-            ('read_only', False),
-            ('read_write', True),
-            ('volume', self._volume.id),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.volumes_mock.update_readonly_flag.assert_called_once_with(
-            self._volume.id, False
-        )
-        self.assertIsNone(result)
-
-
-class TestVolumeShow(TestVolume):
-    columns = (
-        'attachments',
-        'availability_zone',
-        'bootable',
-        'created_at',
-        'display_description',
-        'id',
-        'name',
-        'properties',
-        'size',
-        'snapshot_id',
-        'status',
-        'type',
-    )
-
-    def setUp(self):
-        super().setUp()
-        self._volume = volume_fakes.create_one_volume()
-        self.datalist = (
-            self._volume.attachments,
-            self._volume.availability_zone,
-            self._volume.bootable,
-            self._volume.created_at,
-            self._volume.display_description,
-            self._volume.id,
-            self._volume.display_name,
-            format_columns.DictColumn(self._volume.metadata),
-            self._volume.size,
-            self._volume.snapshot_id,
-            self._volume.status,
-            self._volume.volume_type,
-        )
-        self.volumes_mock.get.return_value = self._volume
-        # Get the command object to test
-        self.cmd = volume.ShowVolume(self.app, None)
-
-    def test_volume_show(self):
-        arglist = [self._volume.id]
-        verifylist = [("volume", self._volume.id)]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.volumes_mock.get.assert_called_with(self._volume.id)
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.datalist, data)
-
-    def test_volume_show_backward_compatibility(self):
-        arglist = [
-            '-c',
-            'display_name',
-            self._volume.id,
-        ]
-        verifylist = [
-            ('columns', ['display_name']),
-            ('volume', self._volume.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.get.assert_called_with(self._volume.id)
-
-        self.assertIn('display_name', columns)
-        self.assertNotIn('name', columns)
-        self.assertIn(self._volume.display_name, data)
-
-
-class TestVolumeUnset(TestVolume):
-    _volume = volume_fakes.create_one_volume()
-
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock.get.return_value = self._volume
-
-        self.volumes_mock.delete_metadata.return_value = None
-        # Get the command object to test
-        self.cmd = volume.UnsetVolume(self.app, None)
-
-    def test_volume_unset_no_options(self):
-        arglist = [
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('property', None),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.assertIsNone(result)
-
-    def test_volume_unset_property(self):
-        arglist = [
-            '--property',
-            'myprop',
-            self._volume.display_name,
-        ]
-        verifylist = [
-            ('property', ['myprop']),
-            ('volume', self._volume.display_name),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.delete_metadata.assert_called_with(
-            self._volume.id, ['myprop']
-        )
-        self.assertIsNone(result)
-
-
-class TestColumns(TestVolume):
-    def test_attachments_column_without_server_cache(self):
-        _volume = volume_fakes.create_one_volume()
-        server_id = _volume.attachments[0]['server_id']
-        device = _volume.attachments[0]['device']
-
-        col = volume.AttachmentsColumn(_volume.attachments, {})
-        self.assertEqual(
-            f'Attached to {server_id} on {device} ',
-            col.human_readable(),
-        )
-        self.assertEqual(_volume.attachments, col.machine_readable())
-
-    def test_attachments_column_with_server_cache(self):
-        _volume = volume_fakes.create_one_volume()
-
-        server_id = _volume.attachments[0]['server_id']
-        device = _volume.attachments[0]['device']
-        fake_server = mock.Mock()
-        fake_server.name = 'fake-server-name'
-        server_cache = {server_id: fake_server}
-
-        col = volume.AttachmentsColumn(_volume.attachments, server_cache)
-        self.assertEqual(
-            'Attached to {} on {} '.format('fake-server-name', device),
-            col.human_readable(),
-        )
-        self.assertEqual(_volume.attachments, col.machine_readable())
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v1/test_volume_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_volume_backup.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v1/test_volume_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v1/test_volume_backup.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,435 +0,0 @@
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-from unittest import mock
-from unittest.mock import call
-
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
-from openstackclient.volume.v1 import volume_backup
-
-
-class TestBackup(volume_fakes.TestVolumev1):
-    def setUp(self):
-        super().setUp()
-
-        self.backups_mock = self.volume_client.backups
-        self.backups_mock.reset_mock()
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-        self.snapshots_mock = self.volume_client.volume_snapshots
-        self.snapshots_mock.reset_mock()
-        self.restores_mock = self.volume_client.restores
-        self.restores_mock.reset_mock()
-
-
-class TestBackupCreate(TestBackup):
-    volume = volume_fakes.create_one_volume()
-
-    columns = (
-        'availability_zone',
-        'container',
-        'description',
-        'id',
-        'name',
-        'object_count',
-        'size',
-        'snapshot_id',
-        'status',
-        'volume_id',
-    )
-
-    def setUp(self):
-        super().setUp()
-        self.new_backup = volume_fakes.create_one_backup(
-            attrs={'volume_id': self.volume.id},
-        )
-        self.data = (
-            self.new_backup.availability_zone,
-            self.new_backup.container,
-            self.new_backup.description,
-            self.new_backup.id,
-            self.new_backup.name,
-            self.new_backup.object_count,
-            self.new_backup.size,
-            self.new_backup.snapshot_id,
-            self.new_backup.status,
-            self.new_backup.volume_id,
-        )
-        self.volumes_mock.get.return_value = self.volume
-        self.backups_mock.create.return_value = self.new_backup
-
-        # Get the command object to test
-        self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
-
-    def test_backup_create(self):
-        arglist = [
-            "--name",
-            self.new_backup.name,
-            "--description",
-            self.new_backup.description,
-            "--container",
-            self.new_backup.container,
-            self.new_backup.volume_id,
-        ]
-        verifylist = [
-            ("name", self.new_backup.name),
-            ("description", self.new_backup.description),
-            ("container", self.new_backup.container),
-            ("volume", self.new_backup.volume_id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.backups_mock.create.assert_called_with(
-            self.new_backup.volume_id,
-            self.new_backup.container,
-            self.new_backup.name,
-            self.new_backup.description,
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, data)
-
-    def test_backup_create_without_name(self):
-        arglist = [
-            "--description",
-            self.new_backup.description,
-            "--container",
-            self.new_backup.container,
-            self.new_backup.volume_id,
-        ]
-        verifylist = [
-            ("description", self.new_backup.description),
-            ("container", self.new_backup.container),
-            ("volume", self.new_backup.volume_id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.backups_mock.create.assert_called_with(
-            self.new_backup.volume_id,
-            self.new_backup.container,
-            None,
-            self.new_backup.description,
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, data)
-
-
-class TestBackupDelete(TestBackup):
-    backups = volume_fakes.create_backups(count=2)
-
-    def setUp(self):
-        super().setUp()
-
-        self.backups_mock.get = volume_fakes.get_backups(self.backups)
-        self.backups_mock.delete.return_value = None
-
-        # Get the command object to mock
-        self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
-
-    def test_backup_delete(self):
-        arglist = [self.backups[0].id]
-        verifylist = [("backups", [self.backups[0].id])]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.backups_mock.delete.assert_called_with(self.backups[0].id)
-        self.assertIsNone(result)
-
-    def test_delete_multiple_backups(self):
-        arglist = []
-        for b in self.backups:
-            arglist.append(b.id)
-        verifylist = [
-            ('backups', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
-
-        calls = []
-        for b in self.backups:
-            calls.append(call(b.id))
-        self.backups_mock.delete.assert_has_calls(calls)
-        self.assertIsNone(result)
-
-    def test_delete_multiple_backups_with_exception(self):
-        arglist = [
-            self.backups[0].id,
-            'unexist_backup',
-        ]
-        verifylist = [
-            ('backups', arglist),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        find_mock_result = [self.backups[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual('1 of 2 backups failed to delete.', str(e))
-
-            find_mock.assert_any_call(self.backups_mock, self.backups[0].id)
-            find_mock.assert_any_call(self.backups_mock, 'unexist_backup')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.backups_mock.delete.assert_called_once_with(
-                self.backups[0].id,
-            )
-
-
-class TestBackupList(TestBackup):
-    volume = volume_fakes.create_one_volume()
-    backups = volume_fakes.create_backups(
-        attrs={'volume_id': volume.display_name},
-        count=3,
-    )
-
-    columns = [
-        'ID',
-        'Name',
-        'Description',
-        'Status',
-        'Size',
-    ]
-    columns_long = columns + [
-        'Availability Zone',
-        'Volume',
-        'Container',
-    ]
-
-    data = []
-    for b in backups:
-        data.append(
-            (
-                b.id,
-                b.name,
-                b.description,
-                b.status,
-                b.size,
-            )
-        )
-    data_long = []
-    for b in backups:
-        data_long.append(
-            (
-                b.id,
-                b.name,
-                b.description,
-                b.status,
-                b.size,
-                b.availability_zone,
-                volume_backup.VolumeIdColumn(b.volume_id),
-                b.container,
-            )
-        )
-
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock.list.return_value = [self.volume]
-        self.backups_mock.list.return_value = self.backups
-        self.volumes_mock.get.return_value = self.volume
-        # Get the command to test
-        self.cmd = volume_backup.ListVolumeBackup(self.app, None)
-
-    def test_backup_list_without_options(self):
-        arglist = []
-        verifylist = [
-            ("long", False),
-            ("name", None),
-            ("status", None),
-            ("volume", None),
-            ('all_projects', False),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        search_opts = {
-            "name": None,
-            "status": None,
-            "volume_id": None,
-            "all_tenants": False,
-        }
-        self.volumes_mock.get.assert_not_called()
-        self.backups_mock.list.assert_called_with(
-            search_opts=search_opts,
-        )
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, list(data))
-
-    def test_backup_list_with_options(self):
-        arglist = [
-            "--long",
-            "--name",
-            self.backups[0].name,
-            "--status",
-            "error",
-            "--volume",
-            self.volume.id,
-            "--all-projects",
-        ]
-        verifylist = [
-            ("long", True),
-            ("name", self.backups[0].name),
-            ("status", "error"),
-            ("volume", self.volume.id),
-            ('all_projects', True),
-        ]
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        search_opts = {
-            "name": self.backups[0].name,
-            "status": "error",
-            "volume_id": self.volume.id,
-            "all_tenants": True,
-        }
-        self.volumes_mock.get.assert_called_once_with(self.volume.id)
-        self.backups_mock.list.assert_called_with(
-            search_opts=search_opts,
-        )
-        self.assertEqual(self.columns_long, columns)
-        self.assertCountEqual(self.data_long, list(data))
-
-
-class TestBackupRestore(TestBackup):
-    volume = volume_fakes.create_one_volume()
-    backup = volume_fakes.create_one_backup(
-        attrs={'volume_id': volume.id},
-    )
-
-    def setUp(self):
-        super().setUp()
-
-        self.backups_mock.get.return_value = self.backup
-        self.volumes_mock.get.return_value = self.volume
-        self.restores_mock.restore.return_value = (
-            volume_fakes.create_one_volume(
-                {'id': self.volume['id']},
-            )
-        )
-        # Get the command object to mock
-        self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
-
-    def test_backup_restore(self):
-        arglist = [
-            self.backup.id,
-        ]
-        verifylist = [
-            ("backup", self.backup.id),
-            ("volume", None),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.restores_mock.restore.assert_called_with(self.backup.id, None)
-        self.assertIsNotNone(result)
-
-    def test_backup_restore_with_existing_volume(self):
-        arglist = [
-            self.backup.id,
-            self.backup.volume_id,
-        ]
-        verifylist = [
-            ("backup", self.backup.id),
-            ("volume", self.backup.volume_id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-        self.restores_mock.restore.assert_called_with(
-            self.backup.id,
-            self.backup.volume_id,
-        )
-        self.assertIsNotNone(result)
-
-    def test_backup_restore_with_invalid_volume(self):
-        arglist = [
-            self.backup.id,
-            "unexist_volume",
-        ]
-        verifylist = [
-            ("backup", self.backup.id),
-            ("volume", "unexist_volume"),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        with mock.patch.object(
-            utils,
-            'find_resource',
-            side_effect=exceptions.CommandError(),
-        ):
-            self.assertRaises(
-                exceptions.CommandError,
-                self.cmd.take_action,
-                parsed_args,
-            )
-
-
-class TestBackupShow(TestBackup):
-    columns = (
-        'availability_zone',
-        'container',
-        'description',
-        'id',
-        'name',
-        'object_count',
-        'size',
-        'snapshot_id',
-        'status',
-        'volume_id',
-    )
-
-    def setUp(self):
-        super().setUp()
-        self.backup = volume_fakes.create_one_backup()
-        self.data = (
-            self.backup.availability_zone,
-            self.backup.container,
-            self.backup.description,
-            self.backup.id,
-            self.backup.name,
-            self.backup.object_count,
-            self.backup.size,
-            self.backup.snapshot_id,
-            self.backup.status,
-            self.backup.volume_id,
-        )
-        self.backups_mock.get.return_value = self.backup
-        # Get the command object to test
-        self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
-
-    def test_backup_show(self):
-        arglist = [self.backup.id]
-        verifylist = [("backup", self.backup.id)]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-        self.backups_mock.get.assert_called_with(self.backup.id)
-
-        self.assertEqual(self.columns, columns)
-        self.assertCountEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v2/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v2/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/fakes.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,7 +14,6 @@
 
 import copy
 import random
-import typing as ty
 from unittest import mock
 import uuid
 
@@ -92,7 +91,7 @@ class FakeClientMixin:
         self.volume_sdk_client = self.app.client_manager.sdk_connection.volume
         self.set_volume_api_version()  # default to the lowest
 
-    def set_volume_api_version(self, version: ty.Optional[str] = None):
+    def set_volume_api_version(self, version: str | None = None):
         """Set a fake block storage API version.
 
         :param version: The fake microversion to "support". This must be None
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v2/test_service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_service.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v2/test_service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_service.py	2025-07-07 22:41:56.000000000 +0000
@@ -12,108 +12,83 @@
 #   under the License.
 #
 
+from unittest import mock
+
+from openstack.block_storage.v2 import service as _service
+from openstack.test import fakes as sdk_fakes
 from osc_lib import exceptions
 
 from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
 from openstackclient.volume.v2 import service
 
 
-class TestService(volume_fakes.TestVolume):
+class TestServiceList(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        # Get a shortcut to the ServiceManager Mock
-        self.service_mock = self.volume_client.services
-        self.service_mock.reset_mock()
-
-
-class TestServiceList(TestService):
-    # The service to be listed
-    services = volume_fakes.create_one_service()
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.volume_sdk_client.services.return_value = [self.service]
 
-    def setUp(self):
-        super().setUp()
-
-        self.service_mock.list.return_value = [self.services]
-
-        # Get the command object to test
         self.cmd = service.ListService(self.app, None)
 
     def test_service_list(self):
         arglist = [
             '--host',
-            self.services.host,
+            self.service.host,
             '--service',
-            self.services.binary,
+            self.service.binary,
         ]
         verifylist = [
-            ('host', self.services.host),
-            ('service', self.services.binary),
+            ('host', self.service.host),
+            ('service', self.service.binary),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        expected_columns = [
+        expected_columns = (
             'Binary',
             'Host',
             'Zone',
             'Status',
             'State',
             'Updated At',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
+        )
         datalist = (
             (
-                self.services.binary,
-                self.services.host,
-                self.services.zone,
-                self.services.status,
-                self.services.state,
-                self.services.updated_at,
+                self.service.binary,
+                self.service.host,
+                self.service.availability_zone,
+                self.service.status,
+                self.service.state,
+                self.service.updated_at,
             ),
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
-
-        # checking if proper call was made to list services
-        self.service_mock.list.assert_called_with(
-            self.services.host,
-            self.services.binary,
+        self.volume_sdk_client.services.assert_called_with(
+            host=self.service.host,
+            binary=self.service.binary,
         )
 
-        # checking if prohibited columns are present in output
-        self.assertNotIn("Disabled Reason", columns)
-        self.assertNotIn(self.services.disabled_reason, tuple(data))
-
     def test_service_list_with_long_option(self):
         arglist = [
             '--host',
-            self.services.host,
+            self.service.host,
             '--service',
-            self.services.binary,
+            self.service.binary,
             '--long',
         ]
         verifylist = [
-            ('host', self.services.host),
-            ('service', self.services.binary),
+            ('host', self.service.host),
+            ('service', self.service.binary),
             ('long', True),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        expected_columns = [
+        expected_columns = (
             'Binary',
             'Host',
             'Zone',
@@ -121,41 +96,34 @@ class TestServiceList(TestService):
             'State',
             'Updated At',
             'Disabled Reason',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
+        )
         datalist = (
             (
-                self.services.binary,
-                self.services.host,
-                self.services.zone,
-                self.services.status,
-                self.services.state,
-                self.services.updated_at,
-                self.services.disabled_reason,
+                self.service.binary,
+                self.service.host,
+                self.service.availability_zone,
+                self.service.status,
+                self.service.state,
+                self.service.updated_at,
+                self.service.disabled_reason,
             ),
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
-
-        self.service_mock.list.assert_called_with(
-            self.services.host,
-            self.services.binary,
+        self.volume_sdk_client.services.assert_called_with(
+            host=self.service.host,
+            binary=self.service.binary,
         )
 
 
-class TestServiceSet(TestService):
-    service = volume_fakes.create_one_service()
-
+class TestServiceSet(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.service_mock.enable.return_value = self.service
-        self.service_mock.disable.return_value = self.service
-        self.service_mock.disable_log_reason.return_value = self.service
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.service.enable = mock.Mock(autospec=True)
+        self.service.disable = mock.Mock(autospec=True)
+        self.volume_sdk_client.find_service.return_value = self.service
 
         self.cmd = service.SetService(self.app, None)
 
@@ -171,9 +139,8 @@ class TestServiceSet(TestService):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
         result = self.cmd.take_action(parsed_args)
 
-        self.service_mock.enable.assert_not_called()
-        self.service_mock.disable.assert_not_called()
-        self.service_mock.disable_log_reason.assert_not_called()
+        self.service.enable.assert_not_called()
+        self.service.disable.assert_not_called()
         self.assertIsNone(result)
 
     def test_service_set_enable(self):
@@ -191,11 +158,8 @@ class TestServiceSet(TestService):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.service_mock.enable.assert_called_with(
-            self.service.host, self.service.binary
-        )
-        self.service_mock.disable.assert_not_called()
-        self.service_mock.disable_log_reason.assert_not_called()
+        self.service.enable.assert_called_with(self.volume_sdk_client)
+        self.service.disable.assert_not_called()
         self.assertIsNone(result)
 
     def test_service_set_disable(self):
@@ -213,11 +177,10 @@ class TestServiceSet(TestService):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.service_mock.disable.assert_called_with(
-            self.service.host, self.service.binary
+        self.service.enable.assert_not_called()
+        self.service.disable.assert_called_with(
+            self.volume_sdk_client, reason=None
         )
-        self.service_mock.enable.assert_not_called()
-        self.service_mock.disable_log_reason.assert_not_called()
         self.assertIsNone(result)
 
     def test_service_set_disable_with_reason(self):
@@ -239,8 +202,9 @@ class TestServiceSet(TestService):
 
         result = self.cmd.take_action(parsed_args)
 
-        self.service_mock.disable_log_reason.assert_called_with(
-            self.service.host, self.service.binary, reason
+        self.service.enable.assert_not_called()
+        self.service.disable.assert_called_with(
+            self.volume_sdk_client, reason=reason
         )
         self.assertIsNone(result)
 
@@ -258,6 +222,7 @@ class TestServiceSet(TestService):
             ('service', self.service.binary),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
         try:
             self.cmd.take_action(parsed_args)
             self.fail("CommandError should be raised.")
@@ -284,6 +249,7 @@ class TestServiceSet(TestService):
             ('service', self.service.binary),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
         try:
             self.cmd.take_action(parsed_args)
             self.fail("CommandError should be raised.")
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume.py	2025-07-07 22:41:56.000000000 +0000
@@ -13,6 +13,9 @@
 
 from unittest import mock
 
+from openstack.block_storage.v2 import volume as _volume
+from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
 from osc_lib.cli import format_columns
 from osc_lib import exceptions
 from osc_lib import utils
@@ -46,12 +49,6 @@ class TestVolume(volume_fakes.TestVolume
         self.consistencygroups_mock = self.volume_client.consistencygroups
         self.consistencygroups_mock.reset_mock()
 
-    def setup_volumes_mock(self, count):
-        volumes = volume_fakes.create_volumes(count=count)
-
-        self.volumes_mock.get = volume_fakes.get_volumes(volumes, 0)
-        return volumes
-
 
 class TestVolumeCreate(TestVolume):
     project = identity_fakes.FakeProject.create_one_project()
@@ -188,7 +185,7 @@ class TestVolumeCreate(TestVolume):
             self.new_volume.name,
         ]
         verifylist = [
-            ('property', {'Alpha': 'a', 'Beta': 'b'}),
+            ('properties', {'Alpha': 'a', 'Beta': 'b'}),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -382,9 +379,7 @@ class TestVolumeCreate(TestVolume):
         ]
         verifylist = [
             ('bootable', True),
-            ('non_bootable', False),
             ('read_only', True),
-            ('read_write', False),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -427,9 +422,7 @@ class TestVolumeCreate(TestVolume):
         ]
         verifylist = [
             ('bootable', False),
-            ('non_bootable', True),
             ('read_only', False),
-            ('read_write', True),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -481,9 +474,7 @@ class TestVolumeCreate(TestVolume):
         ]
         verifylist = [
             ('bootable', True),
-            ('non_bootable', False),
             ('read_only', True),
-            ('read_write', False),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -532,9 +523,7 @@ class TestVolumeCreate(TestVolume):
         ]
         verifylist = [
             ('bootable', False),
-            ('non_bootable', True),
             ('read_only', True),
-            ('read_write', False),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -670,37 +659,37 @@ class TestVolumeCreate(TestVolume):
         self.assertCountEqual(self.datalist, data)
 
 
-class TestVolumeDelete(TestVolume):
+class TestVolumeDelete(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.volumes_mock.delete.return_value = None
+        self.volumes = list(sdk_fakes.generate_fake_resources(_volume.Volume))
+        self.volume_sdk_client.find_volume.side_effect = self.volumes
+        self.volume_sdk_client.delete_volume.return_value = None
 
-        # Get the command object to mock
         self.cmd = volume.DeleteVolume(self.app, None)
 
     def test_volume_delete_one_volume(self):
-        volumes = self.setup_volumes_mock(count=1)
-
-        arglist = [volumes[0].id]
+        arglist = [self.volumes[0].id]
         verifylist = [
             ("force", False),
             ("purge", False),
-            ("volumes", [volumes[0].id]),
+            ("volumes", [self.volumes[0].id]),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.volumes_mock.delete.assert_called_once_with(
-            volumes[0].id, cascade=False
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_called_once_with(
+            self.volumes[0].id, cascade=False, force=False
         )
-        self.assertIsNone(result)
 
     def test_volume_delete_multi_volumes(self):
-        volumes = self.setup_volumes_mock(count=3)
-
-        arglist = [v.id for v in volumes]
+        arglist = [v.id for v in self.volumes]
         verifylist = [
             ('force', False),
             ('purge', False),
@@ -709,83 +698,95 @@ class TestVolumeDelete(TestVolume):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-
-        calls = [mock.call(v.id, cascade=False) for v in volumes]
-        self.volumes_mock.delete.assert_has_calls(calls)
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_volume.assert_has_calls(
+            [mock.call(v.id, ignore_missing=False) for v in self.volumes]
+        )
+        self.volume_sdk_client.delete_volume.assert_has_calls(
+            [mock.call(v.id, cascade=False, force=False) for v in self.volumes]
+        )
+
     def test_volume_delete_multi_volumes_with_exception(self):
-        volumes = self.setup_volumes_mock(count=2)
+        self.volume_sdk_client.find_volume.side_effect = [
+            self.volumes[0],
+            sdk_exceptions.NotFoundException(),
+        ]
 
         arglist = [
-            volumes[0].id,
+            self.volumes[0].id,
             'unexist_volume',
         ]
         verifylist = [
             ('force', False),
             ('purge', False),
-            ('volumes', arglist),
+            ('volumes', [self.volumes[0].id, 'unexist_volume']),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        find_mock_result = [volumes[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual('1 of 2 volumes failed to delete.', str(e))
-
-            find_mock.assert_any_call(self.volumes_mock, volumes[0].id)
-            find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.volumes_mock.delete.assert_called_once_with(
-                volumes[0].id, cascade=False
-            )
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+        self.assertEqual('1 of 2 volumes failed to delete.', str(exc))
 
-    def test_volume_delete_with_purge(self):
-        volumes = self.setup_volumes_mock(count=1)
+        self.volume_sdk_client.find_volume.assert_has_calls(
+            [
+                mock.call(self.volumes[0].id, ignore_missing=False),
+                mock.call('unexist_volume', ignore_missing=False),
+            ]
+        )
+        self.volume_sdk_client.delete_volume.assert_has_calls(
+            [
+                mock.call(self.volumes[0].id, cascade=False, force=False),
+            ]
+        )
 
+    def test_volume_delete_with_purge(self):
         arglist = [
             '--purge',
-            volumes[0].id,
+            self.volumes[0].id,
         ]
         verifylist = [
             ('force', False),
             ('purge', True),
-            ('volumes', [volumes[0].id]),
+            ('volumes', [self.volumes[0].id]),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.volumes_mock.delete.assert_called_once_with(
-            volumes[0].id, cascade=True
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_called_once_with(
+            self.volumes[0].id, cascade=True, force=False
         )
-        self.assertIsNone(result)
 
     def test_volume_delete_with_force(self):
-        volumes = self.setup_volumes_mock(count=1)
-
         arglist = [
             '--force',
-            volumes[0].id,
+            self.volumes[0].id,
         ]
         verifylist = [
             ('force', True),
             ('purge', False),
-            ('volumes', [volumes[0].id]),
+            ('volumes', [self.volumes[0].id]),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.force_delete.assert_called_once_with(volumes[0].id)
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_called_once_with(
+            self.volumes[0].id, cascade=False, force=True
+        )
+
 
 class TestVolumeList(TestVolume):
     project = identity_fakes.FakeProject.create_one_project()
@@ -1407,16 +1408,16 @@ class TestVolumeSet(TestVolume):
             self.new_volume.id,
         ]
         verifylist = [
-            ('property', {'a': 'b', 'c': 'd'}),
+            ('properties', {'a': 'b', 'c': 'd'}),
             ('volume', self.new_volume.id),
-            ('bootable', False),
-            ('non_bootable', False),
+            ('bootable', None),
+            ('read_only', None),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         self.cmd.take_action(parsed_args)
         self.volumes_mock.set_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.property
+            self.new_volume.id, parsed_args.properties
         )
 
     def test_volume_set_image_property(self):
@@ -1428,10 +1429,10 @@ class TestVolumeSet(TestVolume):
             self.new_volume.id,
         ]
         verifylist = [
-            ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
+            ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
             ('volume', self.new_volume.id),
-            ('bootable', False),
-            ('non_bootable', False),
+            ('bootable', None),
+            ('read_only', None),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -1439,14 +1440,13 @@ class TestVolumeSet(TestVolume):
         # returns nothing
         self.cmd.take_action(parsed_args)
         self.volumes_mock.set_image_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.image_property
+            self.new_volume.id, parsed_args.image_properties
         )
 
     def test_volume_set_state(self):
         arglist = ['--state', 'error', self.new_volume.id]
         verifylist = [
-            ('read_only', False),
-            ('read_write', False),
+            ('read_only', None),
             ('state', 'error'),
             ('volume', self.new_volume.id),
         ]
@@ -1511,36 +1511,40 @@ class TestVolumeSet(TestVolume):
 
     def test_volume_set_bootable(self):
         arglist = [
-            ['--bootable', self.new_volume.id],
-            ['--non-bootable', self.new_volume.id],
+            '--bootable',
+            self.new_volume.id,
         ]
         verifylist = [
-            [
-                ('bootable', True),
-                ('non_bootable', False),
-                ('volume', self.new_volume.id),
-            ],
-            [
-                ('bootable', False),
-                ('non_bootable', True),
-                ('volume', self.new_volume.id),
-            ],
-        ]
-        for index in range(len(arglist)):
-            parsed_args = self.check_parser(
-                self.cmd, arglist[index], verifylist[index]
-            )
+            ('bootable', True),
+            ('volume', self.new_volume.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-            self.cmd.take_action(parsed_args)
-            self.volumes_mock.set_bootable.assert_called_with(
-                self.new_volume.id, verifylist[index][0][1]
-            )
+        self.cmd.take_action(parsed_args)
+        self.volumes_mock.set_bootable.assert_called_with(
+            self.new_volume.id, verifylist[0][1]
+        )
+
+    def test_volume_set_non_bootable(self):
+        arglist = [
+            '--non-bootable',
+            self.new_volume.id,
+        ]
+        verifylist = [
+            ('bootable', False),
+            ('volume', self.new_volume.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+        self.volumes_mock.set_bootable.assert_called_with(
+            self.new_volume.id, verifylist[0][1]
+        )
 
-    def test_volume_set_readonly(self):
+    def test_volume_set_read_only(self):
         arglist = ['--read-only', self.new_volume.id]
         verifylist = [
             ('read_only', True),
-            ('read_write', False),
             ('volume', self.new_volume.id),
         ]
 
@@ -1556,7 +1560,6 @@ class TestVolumeSet(TestVolume):
         arglist = ['--read-write', self.new_volume.id]
         verifylist = [
             ('read_only', False),
-            ('read_write', True),
             ('volume', self.new_volume.id),
         ]
 
@@ -1619,7 +1622,7 @@ class TestVolumeSet(TestVolume):
         result = self.cmd.take_action(parsed_args)
         self.volumes_mock.retype.assert_not_called()
         mock_warning.assert_called_with(
-            "'--retype-policy' option will " "not work without '--type' option"
+            "'--retype-policy' option will not work without '--type' option"
         )
         self.assertIsNone(result)
 
@@ -1686,7 +1689,7 @@ class TestVolumeUnset(TestVolume):
             self.new_volume.id,
         ]
         verifylist = [
-            ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
+            ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
             ('volume', self.new_volume.id),
         ]
         parsed_args = self.check_parser(self.cmd_set, arglist, verifylist)
@@ -1702,7 +1705,7 @@ class TestVolumeUnset(TestVolume):
             self.new_volume.id,
         ]
         verifylist_unset = [
-            ('image_property', ['Alpha']),
+            ('image_properties', ['Alpha']),
             ('volume', self.new_volume.id),
         ]
         parsed_args_unset = self.check_parser(
@@ -1714,7 +1717,7 @@ class TestVolumeUnset(TestVolume):
         self.cmd_unset.take_action(parsed_args_unset)
 
         self.volumes_mock.delete_image_metadata.assert_called_with(
-            self.new_volume.id, parsed_args_unset.image_property
+            self.new_volume.id, parsed_args_unset.image_properties
         )
 
     def test_volume_unset_image_property_fail(self):
@@ -1729,8 +1732,8 @@ class TestVolumeUnset(TestVolume):
             self.new_volume.id,
         ]
         verifylist = [
-            ('image_property', ['Alpha']),
-            ('property', ['Beta']),
+            ('image_properties', ['Alpha']),
+            ('properties', ['Beta']),
             ('volume', self.new_volume.id),
         ]
         parsed_args = self.check_parser(self.cmd_unset, arglist, verifylist)
@@ -1743,10 +1746,10 @@ class TestVolumeUnset(TestVolume):
                 'One or more of the unset operations failed', str(e)
             )
         self.volumes_mock.delete_image_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.image_property
+            self.new_volume.id, parsed_args.image_properties
         )
         self.volumes_mock.delete_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.property
+            self.new_volume.id, parsed_args.properties
         )
 
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume_backup.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume_backup.py	2025-07-07 22:41:56.000000000 +0000
@@ -13,89 +13,81 @@
 
 from unittest.mock import call
 
+from openstack.block_storage.v2 import backup as _backup
+from openstack.block_storage.v2 import snapshot as _snapshot
+from openstack.block_storage.v2 import volume as _volume
+from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
 from osc_lib import exceptions
 
 from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
 from openstackclient.volume.v2 import volume_backup
 
 
-class TestBackupLegacy(volume_fakes.TestVolume):
-    def setUp(self):
-        super().setUp()
-
-        self.backups_mock = self.volume_client.backups
-        self.backups_mock.reset_mock()
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-        self.snapshots_mock = self.volume_client.volume_snapshots
-        self.snapshots_mock.reset_mock()
-        self.restores_mock = self.volume_client.restores
-        self.restores_mock.reset_mock()
-
-
 class TestBackupCreate(volume_fakes.TestVolume):
-    volume = volume_fakes.create_one_volume()
-    snapshot = volume_fakes.create_one_snapshot()
-    new_backup = volume_fakes.create_one_backup(
-        attrs={'volume_id': volume.id, 'snapshot_id': snapshot.id}
-    )
-
     columns = (
         'id',
         'name',
         'volume_id',
     )
-    data = (
-        new_backup.id,
-        new_backup.name,
-        new_backup.volume_id,
-    )
 
     def setUp(self):
         super().setUp()
 
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
         self.volume_sdk_client.find_volume.return_value = self.volume
+        self.snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
         self.volume_sdk_client.find_snapshot.return_value = self.snapshot
-        self.volume_sdk_client.create_backup.return_value = self.new_backup
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup,
+            volume_id=self.volume.id,
+            snapshot_id=self.snapshot.id,
+        )
+        self.volume_sdk_client.create_backup.return_value = self.backup
+
+        self.data = (
+            self.backup.id,
+            self.backup.name,
+            self.backup.volume_id,
+        )
 
-        # Get the command object to test
         self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
 
     def test_backup_create(self):
         arglist = [
             "--name",
-            self.new_backup.name,
+            self.backup.name,
             "--description",
-            self.new_backup.description,
+            self.backup.description,
             "--container",
-            self.new_backup.container,
+            self.backup.container,
             "--force",
             "--incremental",
             "--snapshot",
-            self.new_backup.snapshot_id,
-            self.new_backup.volume_id,
+            self.backup.snapshot_id,
+            self.backup.volume_id,
         ]
         verifylist = [
-            ("name", self.new_backup.name),
-            ("description", self.new_backup.description),
-            ("container", self.new_backup.container),
+            ("name", self.backup.name),
+            ("description", self.backup.description),
+            ("container", self.backup.container),
             ("force", True),
             ("incremental", True),
-            ("snapshot", self.new_backup.snapshot_id),
-            ("volume", self.new_backup.volume_id),
+            ("snapshot", self.backup.snapshot_id),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
         self.volume_sdk_client.create_backup.assert_called_with(
-            volume_id=self.new_backup.volume_id,
-            container=self.new_backup.container,
-            name=self.new_backup.name,
-            description=self.new_backup.description,
+            volume_id=self.backup.volume_id,
+            container=self.backup.container,
+            name=self.backup.name,
+            description=self.backup.description,
             force=True,
             is_incremental=True,
-            snapshot_id=self.new_backup.snapshot_id,
+            snapshot_id=self.backup.snapshot_id,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
@@ -103,25 +95,25 @@ class TestBackupCreate(volume_fakes.Test
     def test_backup_create_without_name(self):
         arglist = [
             "--description",
-            self.new_backup.description,
+            self.backup.description,
             "--container",
-            self.new_backup.container,
-            self.new_backup.volume_id,
+            self.backup.container,
+            self.backup.volume_id,
         ]
         verifylist = [
-            ("description", self.new_backup.description),
-            ("container", self.new_backup.container),
-            ("volume", self.new_backup.volume_id),
+            ("description", self.backup.description),
+            ("container", self.backup.container),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
         self.volume_sdk_client.create_backup.assert_called_with(
-            volume_id=self.new_backup.volume_id,
-            container=self.new_backup.container,
+            volume_id=self.backup.volume_id,
+            container=self.backup.container,
             name=None,
-            description=self.new_backup.description,
+            description=self.backup.description,
             force=False,
             is_incremental=False,
         )
@@ -130,17 +122,13 @@ class TestBackupCreate(volume_fakes.Test
 
 
 class TestBackupDelete(volume_fakes.TestVolume):
-    backups = volume_fakes.create_backups(count=2)
-
     def setUp(self):
         super().setUp()
 
-        self.volume_sdk_client.find_backup = volume_fakes.get_backups(
-            self.backups
-        )
+        self.backups = list(sdk_fakes.generate_fake_resources(_backup.Backup))
+        self.volume_sdk_client.find_backup.side_effect = self.backups
         self.volume_sdk_client.delete_backup.return_value = None
 
-        # Get the command object to mock
         self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
 
     def test_backup_delete(self):
@@ -223,11 +211,6 @@ class TestBackupDelete(volume_fakes.Test
 
 
 class TestBackupList(volume_fakes.TestVolume):
-    volume = volume_fakes.create_one_volume()
-    backups = volume_fakes.create_backups(
-        attrs={'volume_id': volume.name}, count=3
-    )
-
     columns = (
         'ID',
         'Name',
@@ -243,45 +226,51 @@ class TestBackupList(volume_fakes.TestVo
         'Container',
     )
 
-    data = []
-    for b in backups:
-        data.append(
-            (
-                b.id,
-                b.name,
-                b.description,
-                b.status,
-                b.size,
-                b.is_incremental,
-                b.created_at,
-            )
-        )
-    data_long = []
-    for b in backups:
-        data_long.append(
-            (
-                b.id,
-                b.name,
-                b.description,
-                b.status,
-                b.size,
-                b.is_incremental,
-                b.created_at,
-                b.availability_zone,
-                volume_backup.VolumeIdColumn(b.volume_id),
-                b.container,
-            )
-        )
-
     def setUp(self):
         super().setUp()
 
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = self.volume
         self.volume_sdk_client.volumes.return_value = [self.volume]
+        self.backups = list(
+            sdk_fakes.generate_fake_resources(
+                _backup.Backup,
+                attrs={'volume_id': self.volume.id},
+            )
+        )
         self.volume_sdk_client.backups.return_value = self.backups
-        self.volume_sdk_client.find_volume.return_value = self.volume
         self.volume_sdk_client.find_backup.return_value = self.backups[0]
 
-        # Get the command to test
+        self.data = []
+        for b in self.backups:
+            self.data.append(
+                (
+                    b.id,
+                    b.name,
+                    b.description,
+                    b.status,
+                    b.size,
+                    b.is_incremental,
+                    b.created_at,
+                )
+            )
+        self.data_long = []
+        for b in self.backups:
+            self.data_long.append(
+                (
+                    b.id,
+                    b.name,
+                    b.description,
+                    b.status,
+                    b.size,
+                    b.is_incremental,
+                    b.created_at,
+                    b.availability_zone,
+                    volume_backup.VolumeIdColumn(b.volume_id),
+                    b.container,
+                )
+            )
+
         self.cmd = volume_backup.ListVolumeBackup(self.app, None)
 
     def test_backup_list_without_options(self):
@@ -359,35 +348,33 @@ class TestBackupList(volume_fakes.TestVo
 
 
 class TestBackupRestore(volume_fakes.TestVolume):
-    volume = volume_fakes.create_one_volume()
-    backup = volume_fakes.create_one_backup(
-        attrs={'volume_id': volume.id},
-    )
-
     columns = (
         "id",
         "volume_id",
         "volume_name",
     )
 
-    data = (
-        backup.id,
-        volume.id,
-        volume.name,
-    )
-
     def setUp(self):
         super().setUp()
 
-        self.volume_sdk_client.find_backup.return_value = self.backup
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
         self.volume_sdk_client.find_volume.return_value = self.volume
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup, volume_id=self.volume.id
+        )
+        self.volume_sdk_client.find_backup.return_value = self.backup
         self.volume_sdk_client.restore_backup.return_value = {
             'id': self.backup['id'],
             'volume_id': self.volume['id'],
             'volume_name': self.volume['name'],
         }
 
-        # Get the command object to mock
+        self.data = (
+            self.backup.id,
+            self.volume.id,
+            self.volume.name,
+        )
+
         self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
 
     def test_backup_restore(self):
@@ -476,17 +463,15 @@ class TestBackupRestore(volume_fakes.Tes
         )
 
 
-class TestBackupSet(TestBackupLegacy):
-    backup = volume_fakes.create_one_backup(
-        attrs={'metadata': {'wow': 'cool'}},
-    )
-
+class TestBackupSet(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.backups_mock.get.return_value = self.backup
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup, metadata={'wow': 'cool'}
+        )
+        self.volume_sdk_client.find_backup.return_value = self.backup
 
-        # Get the command object to test
         self.cmd = volume_backup.SetVolumeBackup(self.app, None)
 
     def test_backup_set_state(self):
@@ -496,32 +481,38 @@ class TestBackupSet(TestBackupLegacy):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.backups_mock.reset_state.assert_called_once_with(
-            self.backup.id, 'error'
-        )
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_backup_status.assert_called_with(
+            self.backup, status='error'
+        )
+
     def test_backup_set_state_failed(self):
-        self.backups_mock.reset_state.side_effect = exceptions.CommandError()
+        self.volume_sdk_client.reset_backup_status.side_effect = (
+            sdk_exceptions.NotFoundException('foo')
+        )
+
         arglist = ['--state', 'error', self.backup.id]
         verifylist = [('state', 'error'), ('backup', self.backup.id)]
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail('CommandError should be raised.')
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                'One or more of the set operations failed', str(e)
-            )
-        self.backups_mock.reset_state.assert_called_with(
-            self.backup.id, 'error'
+        exc = self.assertRaises(
+            exceptions.CommandError, self.cmd.take_action, parsed_args
+        )
+        self.assertEqual('One or more of the set operations failed', str(exc))
+
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_backup_status.assert_called_with(
+            self.backup, status='error'
         )
 
 
 class TestBackupShow(volume_fakes.TestVolume):
-    backup = volume_fakes.create_one_backup()
-
     columns = (
         "availability_zone",
         "container",
@@ -540,30 +531,32 @@ class TestBackupShow(volume_fakes.TestVo
         "updated_at",
         "volume_id",
     )
-    data = (
-        backup.availability_zone,
-        backup.container,
-        backup.created_at,
-        backup.data_timestamp,
-        backup.description,
-        backup.fail_reason,
-        backup.has_dependent_backups,
-        backup.id,
-        backup.is_incremental,
-        backup.name,
-        backup.object_count,
-        backup.size,
-        backup.snapshot_id,
-        backup.status,
-        backup.updated_at,
-        backup.volume_id,
-    )
 
     def setUp(self):
         super().setUp()
 
+        self.backup = sdk_fakes.generate_fake_resource(_backup.Backup)
         self.volume_sdk_client.find_backup.return_value = self.backup
-        # Get the command object to test
+
+        self.data = (
+            self.backup.availability_zone,
+            self.backup.container,
+            self.backup.created_at,
+            self.backup.data_timestamp,
+            self.backup.description,
+            self.backup.fail_reason,
+            self.backup.has_dependent_backups,
+            self.backup.id,
+            self.backup.is_incremental,
+            self.backup.name,
+            self.backup.object_count,
+            self.backup.size,
+            self.backup.snapshot_id,
+            self.backup.status,
+            self.backup.updated_at,
+            self.backup.volume_id,
+        )
+
         self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
 
     def test_backup_show(self):
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume_snapshot.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume_snapshot.py	2025-07-07 22:41:56.000000000 +0000
@@ -13,9 +13,12 @@
 
 from unittest import mock
 
+from openstack.block_storage.v2 import snapshot as _snapshot
+from openstack.block_storage.v3 import volume as _volume
+from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
 from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.tests.unit.identity.v3 import fakes as project_fakes
 from openstackclient.tests.unit import utils as test_utils
@@ -23,19 +26,7 @@ from openstackclient.tests.unit.volume.v
 from openstackclient.volume.v2 import volume_snapshot
 
 
-class TestVolumeSnapshot(volume_fakes.TestVolume):
-    def setUp(self):
-        super().setUp()
-
-        self.snapshots_mock = self.volume_client.volume_snapshots
-        self.snapshots_mock.reset_mock()
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-        self.project_mock = self.identity_client.projects
-        self.project_mock.reset_mock()
-
-
-class TestVolumeSnapshotCreate(TestVolumeSnapshot):
+class TestVolumeSnapshotCreate(volume_fakes.TestVolume):
     columns = (
         'created_at',
         'description',
@@ -50,69 +41,71 @@ class TestVolumeSnapshotCreate(TestVolum
     def setUp(self):
         super().setUp()
 
-        self.volume = volume_fakes.create_one_volume()
-        self.new_snapshot = volume_fakes.create_one_snapshot(
-            attrs={'volume_id': self.volume.id}
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = self.volume
+        self.snapshot = sdk_fakes.generate_fake_resource(
+            _snapshot.Snapshot, volume_id=self.volume.id
         )
+        self.volume_sdk_client.create_snapshot.return_value = self.snapshot
+        self.volume_sdk_client.manage_snapshot.return_value = self.snapshot
 
         self.data = (
-            self.new_snapshot.created_at,
-            self.new_snapshot.description,
-            self.new_snapshot.id,
-            self.new_snapshot.name,
-            format_columns.DictColumn(self.new_snapshot.metadata),
-            self.new_snapshot.size,
-            self.new_snapshot.status,
-            self.new_snapshot.volume_id,
+            self.snapshot.created_at,
+            self.snapshot.description,
+            self.snapshot.id,
+            self.snapshot.name,
+            format_columns.DictColumn(self.snapshot.metadata),
+            self.snapshot.size,
+            self.snapshot.status,
+            self.snapshot.volume_id,
         )
 
-        self.volumes_mock.get.return_value = self.volume
-        self.snapshots_mock.create.return_value = self.new_snapshot
-        self.snapshots_mock.manage.return_value = self.new_snapshot
-        # Get the command object to test
         self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None)
 
     def test_snapshot_create(self):
         arglist = [
             "--volume",
-            self.new_snapshot.volume_id,
+            self.snapshot.volume_id,
             "--description",
-            self.new_snapshot.description,
+            self.snapshot.description,
             "--force",
             '--property',
             'Alpha=a',
             '--property',
             'Beta=b',
-            self.new_snapshot.name,
+            self.snapshot.name,
         ]
         verifylist = [
-            ("volume", self.new_snapshot.volume_id),
-            ("description", self.new_snapshot.description),
+            ("volume", self.snapshot.volume_id),
+            ("description", self.snapshot.description),
             ("force", True),
-            ('property', {'Alpha': 'a', 'Beta': 'b'}),
-            ("snapshot_name", self.new_snapshot.name),
+            ('properties', {'Alpha': 'a', 'Beta': 'b'}),
+            ("snapshot_name", self.snapshot.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.create.assert_called_with(
-            self.new_snapshot.volume_id,
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.snapshot.volume_id, ignore_missing=False
+        )
+        self.volume_sdk_client.create_snapshot.assert_called_with(
+            volume_id=self.snapshot.volume_id,
             force=True,
-            name=self.new_snapshot.name,
-            description=self.new_snapshot.description,
+            name=self.snapshot.name,
+            description=self.snapshot.description,
             metadata={'Alpha': 'a', 'Beta': 'b'},
         )
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
 
     def test_snapshot_create_without_name(self):
         arglist = [
             "--volume",
-            self.new_snapshot.volume_id,
+            self.snapshot.volume_id,
         ]
         verifylist = [
-            ("volume", self.new_snapshot.volume_id),
+            ("volume", self.snapshot.volume_id),
         ]
         self.assertRaises(
             test_utils.ParserException,
@@ -125,29 +118,31 @@ class TestVolumeSnapshotCreate(TestVolum
     def test_snapshot_create_without_volume(self):
         arglist = [
             "--description",
-            self.new_snapshot.description,
+            self.snapshot.description,
             "--force",
-            self.new_snapshot.name,
+            self.snapshot.name,
         ]
         verifylist = [
-            ("description", self.new_snapshot.description),
+            ("description", self.snapshot.description),
             ("force", True),
-            ("snapshot_name", self.new_snapshot.name),
+            ("snapshot_name", self.snapshot.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.volumes_mock.get.assert_called_once_with(self.new_snapshot.name)
-        self.snapshots_mock.create.assert_called_once_with(
-            self.new_snapshot.volume_id,
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.snapshot.name, ignore_missing=False
+        )
+        self.volume_sdk_client.create_snapshot.assert_called_once_with(
+            volume_id=self.snapshot.volume_id,
             force=True,
-            name=self.new_snapshot.name,
-            description=self.new_snapshot.description,
+            name=self.snapshot.name,
+            description=self.snapshot.description,
             metadata=None,
         )
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
 
     def test_snapshot_create_with_remote_source(self):
         arglist = [
@@ -156,8 +151,8 @@ class TestVolumeSnapshotCreate(TestVolum
             '--remote-source',
             'source-id=test_source_id',
             '--volume',
-            self.new_snapshot.volume_id,
-            self.new_snapshot.name,
+            self.snapshot.volume_id,
+            self.snapshot.name,
         ]
         ref_dict = {
             'source-name': 'test_source_name',
@@ -165,35 +160,38 @@ class TestVolumeSnapshotCreate(TestVolum
         }
         verifylist = [
             ('remote_source', ref_dict),
-            ('volume', self.new_snapshot.volume_id),
-            ("snapshot_name", self.new_snapshot.name),
+            ('volume', self.snapshot.volume_id),
+            ("snapshot_name", self.snapshot.name),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.manage.assert_called_with(
-            volume_id=self.new_snapshot.volume_id,
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.snapshot.volume_id, ignore_missing=False
+        )
+        self.volume_sdk_client.manage_snapshot.assert_called_with(
+            volume_id=self.snapshot.volume_id,
             ref=ref_dict,
-            name=self.new_snapshot.name,
+            name=self.snapshot.name,
             description=None,
             metadata=None,
         )
-        self.snapshots_mock.create.assert_not_called()
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
+        self.volume_sdk_client.create_snapshot.assert_not_called()
 
 
-class TestVolumeSnapshotDelete(TestVolumeSnapshot):
-    snapshots = volume_fakes.create_snapshots(count=2)
-
+class TestVolumeSnapshotDelete(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.snapshots_mock.get = volume_fakes.get_snapshots(self.snapshots)
-        self.snapshots_mock.delete.return_value = None
+        self.snapshots = list(
+            sdk_fakes.generate_fake_resources(_snapshot.Snapshot)
+        )
+        self.volume_sdk_client.find_snapshot.side_effect = self.snapshots
+        self.volume_sdk_client.delete_snapshot.return_value = None
 
-        # Get the command object to mock
         self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
 
     def test_snapshot_delete(self):
@@ -202,11 +200,14 @@ class TestVolumeSnapshotDelete(TestVolum
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.snapshots_mock.delete.assert_called_with(
-            self.snapshots[0].id, False
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            self.snapshots[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_snapshot.assert_called_once_with(
+            self.snapshots[0].id, force=False
         )
-        self.assertIsNone(result)
 
     def test_snapshot_delete_with_force(self):
         arglist = ['--force', self.snapshots[0].id]
@@ -214,11 +215,14 @@ class TestVolumeSnapshotDelete(TestVolum
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.snapshots_mock.delete.assert_called_with(
-            self.snapshots[0].id, True
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            self.snapshots[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_snapshot.assert_called_once_with(
+            self.snapshots[0].id, force=True
         )
-        self.assertIsNone(result)
 
     def test_delete_multiple_snapshots(self):
         arglist = []
@@ -227,17 +231,24 @@ class TestVolumeSnapshotDelete(TestVolum
         verifylist = [
             ('snapshots', arglist),
         ]
-
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
 
-        calls = []
-        for s in self.snapshots:
-            calls.append(mock.call(s.id, False))
-        self.snapshots_mock.delete.assert_has_calls(calls)
+        result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_snapshot.assert_has_calls(
+            [mock.call(x.id, ignore_missing=False) for x in self.snapshots]
+        )
+        self.volume_sdk_client.delete_snapshot.assert_has_calls(
+            [mock.call(x.id, force=False) for x in self.snapshots]
+        )
+
     def test_delete_multiple_snapshots_with_exception(self):
+        self.volume_sdk_client.find_snapshot.side_effect = [
+            self.snapshots[0],
+            sdk_exceptions.NotFoundException(),
+        ]
+
         arglist = [
             self.snapshots[0].id,
             'unexist_snapshot',
@@ -248,73 +259,77 @@ class TestVolumeSnapshotDelete(TestVolum
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        find_mock_result = [self.snapshots[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual('1 of 2 snapshots failed to delete.', str(e))
-
-            find_mock.assert_any_call(
-                self.snapshots_mock, self.snapshots[0].id
-            )
-            find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.snapshots_mock.delete.assert_called_once_with(
-                self.snapshots[0].id, False
-            )
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+        self.assertEqual('1 of 2 snapshots failed to delete.', str(exc))
 
+        self.volume_sdk_client.find_snapshot.assert_has_calls(
+            [
+                mock.call(self.snapshots[0].id, ignore_missing=False),
+                mock.call('unexist_snapshot', ignore_missing=False),
+            ]
+        )
+        self.volume_sdk_client.delete_snapshot.assert_has_calls(
+            [
+                mock.call(self.snapshots[0].id, force=False),
+            ]
+        )
 
-class TestVolumeSnapshotList(TestVolumeSnapshot):
-    volume = volume_fakes.create_one_volume()
-    project = project_fakes.FakeProject.create_one_project()
-    snapshots = volume_fakes.create_snapshots(
-        attrs={'volume_id': volume.name}, count=3
-    )
 
-    columns = ["ID", "Name", "Description", "Status", "Size"]
-    columns_long = columns + ["Created At", "Volume", "Properties"]
+class TestVolumeSnapshotList(volume_fakes.TestVolume):
+    def setUp(self):
+        super().setUp()
 
-    data = []
-    for s in snapshots:
-        data.append(
-            (
-                s.id,
-                s.name,
-                s.description,
-                s.status,
-                s.size,
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.snapshots = list(
+            sdk_fakes.generate_fake_resources(
+                _snapshot.Snapshot, attrs={'volume_id': self.volume.name}
             )
         )
-    data_long = []
-    for s in snapshots:
-        data_long.append(
-            (
-                s.id,
-                s.name,
-                s.description,
-                s.status,
-                s.size,
-                s.created_at,
-                volume_snapshot.VolumeIdColumn(
-                    s.volume_id, volume_cache={volume.id: volume}
-                ),
-                format_columns.DictColumn(s.metadata),
-            )
+        self.project = project_fakes.FakeProject.create_one_project()
+        self.volume_sdk_client.volumes.return_value = [self.volume]
+        self.volume_sdk_client.find_volume.return_value = self.volume
+        self.volume_sdk_client.snapshots.return_value = self.snapshots
+        self.project_mock = self.identity_client.projects
+        self.project_mock.get.return_value = self.project
+
+        self.columns = ("ID", "Name", "Description", "Status", "Size")
+        self.columns_long = self.columns + (
+            "Created At",
+            "Volume",
+            "Properties",
         )
 
-    def setUp(self):
-        super().setUp()
+        self.data = []
+        self.data_long = []
+        for s in self.snapshots:
+            self.data.append(
+                (
+                    s.id,
+                    s.name,
+                    s.description,
+                    s.status,
+                    s.size,
+                )
+            )
+            self.data_long.append(
+                (
+                    s.id,
+                    s.name,
+                    s.description,
+                    s.status,
+                    s.size,
+                    s.created_at,
+                    volume_snapshot.VolumeIdColumn(
+                        s.volume_id, volume_cache={self.volume.id: self.volume}
+                    ),
+                    format_columns.DictColumn(s.metadata),
+                )
+            )
 
-        self.volumes_mock.list.return_value = [self.volume]
-        self.volumes_mock.get.return_value = self.volume
-        self.project_mock.get.return_value = self.project
-        self.snapshots_mock.list.return_value = self.snapshots
-        # Get the command to test
         self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
 
     def test_snapshot_list_without_options(self):
@@ -324,16 +339,14 @@ class TestVolumeSnapshotList(TestVolumeS
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.list.assert_called_once_with(
+        self.volume_sdk_client.snapshots.assert_called_once_with(
             limit=None,
             marker=None,
-            search_opts={
-                'all_tenants': False,
-                'name': None,
-                'status': None,
-                'project_id': None,
-                'volume_id': None,
-            },
+            all_projects=False,
+            name=None,
+            status=None,
+            project_id=None,
+            volume_id=None,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
@@ -359,16 +372,14 @@ class TestVolumeSnapshotList(TestVolumeS
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.list.assert_called_once_with(
+        self.volume_sdk_client.snapshots.assert_called_once_with(
             limit=2,
             marker=self.snapshots[0].id,
-            search_opts={
-                'all_tenants': True,
-                'project_id': self.project.id,
-                'name': None,
-                'status': None,
-                'volume_id': None,
-            },
+            all_projects=True,
+            project_id=self.project.id,
+            name=None,
+            status=None,
+            volume_id=None,
         )
         self.assertEqual(self.columns_long, columns)
         self.assertEqual(self.data_long, list(data))
@@ -382,16 +393,14 @@ class TestVolumeSnapshotList(TestVolumeS
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.list.assert_called_once_with(
+        self.volume_sdk_client.snapshots.assert_called_once_with(
             limit=None,
             marker=None,
-            search_opts={
-                'all_tenants': True,
-                'name': None,
-                'status': None,
-                'project_id': None,
-                'volume_id': None,
-            },
+            all_projects=True,
+            name=None,
+            status=None,
+            project_id=None,
+            volume_id=None,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
@@ -410,16 +419,14 @@ class TestVolumeSnapshotList(TestVolumeS
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.list.assert_called_once_with(
+        self.volume_sdk_client.snapshots.assert_called_once_with(
             limit=None,
             marker=None,
-            search_opts={
-                'all_tenants': False,
-                'name': self.snapshots[0].name,
-                'status': None,
-                'project_id': None,
-                'volume_id': None,
-            },
+            all_projects=False,
+            name=self.snapshots[0].name,
+            status=None,
+            project_id=None,
+            volume_id=None,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
@@ -427,27 +434,25 @@ class TestVolumeSnapshotList(TestVolumeS
     def test_snapshot_list_status_option(self):
         arglist = [
             '--status',
-            self.snapshots[0].status,
+            'available',
         ]
         verifylist = [
             ('all_projects', False),
             ('long', False),
-            ('status', self.snapshots[0].status),
+            ('status', 'available'),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.list.assert_called_once_with(
+        self.volume_sdk_client.snapshots.assert_called_once_with(
             limit=None,
             marker=None,
-            search_opts={
-                'all_tenants': False,
-                'name': None,
-                'status': self.snapshots[0].status,
-                'project_id': None,
-                'volume_id': None,
-            },
+            all_projects=False,
+            name=None,
+            status='available',
+            project_id=None,
+            volume_id=None,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
@@ -466,16 +471,14 @@ class TestVolumeSnapshotList(TestVolumeS
 
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.list.assert_called_once_with(
+        self.volume_sdk_client.snapshots.assert_called_once_with(
             limit=None,
             marker=None,
-            search_opts={
-                'all_tenants': False,
-                'name': None,
-                'status': None,
-                'project_id': None,
-                'volume_id': self.volume.id,
-            },
+            all_projects=False,
+            name=None,
+            status=None,
+            project_id=None,
+            volume_id=self.volume.id,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
@@ -497,16 +500,18 @@ class TestVolumeSnapshotList(TestVolumeS
         )
 
 
-class TestVolumeSnapshotSet(TestVolumeSnapshot):
-    snapshot = volume_fakes.create_one_snapshot()
-
+class TestVolumeSnapshotSet(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.snapshots_mock.get.return_value = self.snapshot
-        self.snapshots_mock.set_metadata.return_value = None
-        self.snapshots_mock.update.return_value = None
-        # Get the command object to mock
+        self.snapshot = sdk_fakes.generate_fake_resource(
+            _snapshot.Snapshot, metadata={'foo': 'bar'}
+        )
+        self.volume_sdk_client.find_snapshot.return_value = self.snapshot
+        self.volume_sdk_client.delete_snapshot_metadata.return_value = None
+        self.volume_sdk_client.set_snapshot_metadata.return_value = None
+        self.volume_sdk_client.update_snapshot.return_value = None
+
         self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None)
 
     def test_snapshot_set_no_option(self):
@@ -519,11 +524,14 @@ class TestVolumeSnapshotSet(TestVolumeSn
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
-        self.assertNotCalled(self.snapshots_mock.reset_state)
-        self.assertNotCalled(self.snapshots_mock.update)
-        self.assertNotCalled(self.snapshots_mock.set_metadata)
+
         self.assertIsNone(result)
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            parsed_args.snapshot, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_snapshot_status.assert_not_called()
+        self.volume_sdk_client.update_snapshot.assert_not_called()
+        self.volume_sdk_client.set_snapshot_metadata.assert_not_called()
 
     def test_snapshot_set_name_and_property(self):
         arglist = [
@@ -535,26 +543,22 @@ class TestVolumeSnapshotSet(TestVolumeSn
             "foo=foo",
             self.snapshot.id,
         ]
-        new_property = {"x": "y", "foo": "foo"}
         verifylist = [
             ("name", "new_snapshot"),
-            ("property", new_property),
+            ("properties", {"x": "y", "foo": "foo"}),
             ("snapshot", self.snapshot.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
 
-        kwargs = {
-            "name": "new_snapshot",
-        }
-        self.snapshots_mock.update.assert_called_with(
-            self.snapshot.id, **kwargs
+        self.assertIsNone(result)
+        self.volume_sdk_client.update_snapshot.assert_called_with(
+            self.snapshot.id, name="new_snapshot"
         )
-        self.snapshots_mock.set_metadata.assert_called_with(
-            self.snapshot.id, new_property
+        self.volume_sdk_client.set_snapshot_metadata.assert_called_with(
+            self.snapshot.id, x="y", foo="foo"
         )
-        self.assertIsNone(result)
 
     def test_snapshot_set_with_no_property(self):
         arglist = [
@@ -568,14 +572,17 @@ class TestVolumeSnapshotSet(TestVolumeSn
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
-        self.assertNotCalled(self.snapshots_mock.reset_state)
-        self.assertNotCalled(self.snapshots_mock.update)
-        self.assertNotCalled(self.snapshots_mock.set_metadata)
-        self.snapshots_mock.delete_metadata.assert_called_with(
-            self.snapshot.id, ["foo"]
-        )
+
         self.assertIsNone(result)
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            parsed_args.snapshot, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_snapshot_status.assert_not_called()
+        self.volume_sdk_client.update_snapshot.assert_not_called()
+        self.volume_sdk_client.set_snapshot_metadata.assert_not_called()
+        self.volume_sdk_client.delete_snapshot_metadata.assert_called_with(
+            self.snapshot.id, keys=["foo"]
+        )
 
     def test_snapshot_set_with_no_property_and_property(self):
         arglist = [
@@ -586,22 +593,26 @@ class TestVolumeSnapshotSet(TestVolumeSn
         ]
         verifylist = [
             ("no_property", True),
-            ("property", {"foo_1": "bar_1"}),
+            ("properties", {"foo_1": "bar_1"}),
             ("snapshot", self.snapshot.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.snapshots_mock.get.assert_called_once_with(parsed_args.snapshot)
-        self.assertNotCalled(self.snapshots_mock.reset_state)
-        self.assertNotCalled(self.snapshots_mock.update)
-        self.snapshots_mock.delete_metadata.assert_called_with(
-            self.snapshot.id, ["foo"]
+
+        self.assertIsNone(result)
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            parsed_args.snapshot, ignore_missing=False
         )
-        self.snapshots_mock.set_metadata.assert_called_once_with(
-            self.snapshot.id, {"foo_1": "bar_1"}
+        self.volume_sdk_client.reset_snapshot_status.assert_not_called()
+        self.volume_sdk_client.update_snapshot.assert_not_called()
+        self.volume_sdk_client.delete_snapshot_metadata.assert_called_with(
+            self.snapshot.id, keys=["foo"]
+        )
+        self.volume_sdk_client.set_snapshot_metadata.assert_called_once_with(
+            self.snapshot.id,
+            foo_1="bar_1",
         )
-        self.assertIsNone(result)
 
     def test_snapshot_set_state_to_error(self):
         arglist = ["--state", "error", self.snapshot.id]
@@ -610,30 +621,32 @@ class TestVolumeSnapshotSet(TestVolumeSn
 
         result = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.reset_state.assert_called_with(
+        self.assertIsNone(result)
+        self.volume_sdk_client.reset_snapshot_status.assert_called_with(
             self.snapshot.id, "error"
         )
-        self.assertIsNone(result)
 
     def test_volume_set_state_failed(self):
-        self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
+        self.volume_sdk_client.reset_snapshot_status.side_effect = (
+            exceptions.CommandError()
+        )
         arglist = ['--state', 'error', self.snapshot.id]
         verifylist = [('state', 'error'), ('snapshot', self.snapshot.id)]
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail('CommandError should be raised.')
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                'One or more of the set operations failed', str(e)
-            )
-        self.snapshots_mock.reset_state.assert_called_once_with(
+
+        exc = self.assertRaises(
+            exceptions.CommandError, self.cmd.take_action, parsed_args
+        )
+        self.assertEqual('One or more of the set operations failed', str(exc))
+        self.volume_sdk_client.reset_snapshot_status.assert_called_once_with(
             self.snapshot.id, 'error'
         )
 
     def test_volume_set_name_and_state_failed(self):
-        self.snapshots_mock.reset_state.side_effect = exceptions.CommandError()
+        self.volume_sdk_client.reset_snapshot_status.side_effect = (
+            exceptions.CommandError()
+        )
         arglist = [
             '--state',
             'error',
@@ -646,43 +659,39 @@ class TestVolumeSnapshotSet(TestVolumeSn
             ("name", "new_snapshot"),
             ('snapshot', self.snapshot.id),
         ]
-
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail('CommandError should be raised.')
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                'One or more of the set operations failed', str(e)
-            )
-        kwargs = {
-            "name": "new_snapshot",
-        }
-        self.snapshots_mock.update.assert_called_once_with(
-            self.snapshot.id, **kwargs
+
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+
+        self.assertEqual('One or more of the set operations failed', str(exc))
+        self.volume_sdk_client.update_snapshot.assert_called_once_with(
+            self.snapshot.id, name="new_snapshot"
         )
-        self.snapshots_mock.reset_state.assert_called_once_with(
+        self.volume_sdk_client.reset_snapshot_status.assert_called_once_with(
             self.snapshot.id, 'error'
         )
 
 
-class TestVolumeSnapshotShow(TestVolumeSnapshot):
-    columns = (
-        'created_at',
-        'description',
-        'id',
-        'name',
-        'properties',
-        'size',
-        'status',
-        'volume_id',
-    )
-
+class TestVolumeSnapshotShow(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.snapshot = volume_fakes.create_one_snapshot()
+        self.snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
 
+        self.columns = (
+            'created_at',
+            'description',
+            'id',
+            'name',
+            'properties',
+            'size',
+            'status',
+            'volume_id',
+        )
         self.data = (
             self.snapshot.created_at,
             self.snapshot.description,
@@ -694,8 +703,8 @@ class TestVolumeSnapshotShow(TestVolumeS
             self.snapshot.volume_id,
         )
 
-        self.snapshots_mock.get.return_value = self.snapshot
-        # Get the command object to test
+        self.volume_sdk_client.find_snapshot.return_value = self.snapshot
+
         self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
 
     def test_snapshot_show(self):
@@ -704,21 +713,22 @@ class TestVolumeSnapshotShow(TestVolumeS
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.snapshots_mock.get.assert_called_with(self.snapshot.id)
+        self.volume_sdk_client.find_snapshot.assert_called_with(
+            self.snapshot.id, ignore_missing=False
+        )
 
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
 
 
-class TestVolumeSnapshotUnset(TestVolumeSnapshot):
-    snapshot = volume_fakes.create_one_snapshot()
-
+class TestVolumeSnapshotUnset(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.snapshots_mock.get.return_value = self.snapshot
-        self.snapshots_mock.delete_metadata.return_value = None
-        # Get the command object to mock
+        self.snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
+        self.volume_sdk_client.find_snapshot.return_value = self.snapshot
+        self.volume_sdk_client.delete_snapshot_metadata.return_value = None
+
         self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None)
 
     def test_snapshot_unset(self):
@@ -728,7 +738,7 @@ class TestVolumeSnapshotUnset(TestVolume
             self.snapshot.id,
         ]
         verifylist = [
-            ("property", ["foo"]),
+            ("properties", ["foo"]),
             ("snapshot", self.snapshot.id),
         ]
 
@@ -736,7 +746,7 @@ class TestVolumeSnapshotUnset(TestVolume
 
         result = self.cmd.take_action(parsed_args)
 
-        self.snapshots_mock.delete_metadata.assert_called_with(
-            self.snapshot.id, ["foo"]
-        )
         self.assertIsNone(result)
+        self.volume_sdk_client.delete_snapshot_metadata.assert_called_with(
+            self.snapshot.id, keys=["foo"]
+        )
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py	2025-07-07 22:41:56.000000000 +0000
@@ -241,7 +241,7 @@ class TestTransferDelete(TestTransfer):
                 self.fail('CommandError should be raised.')
             except exceptions.CommandError as e:
                 self.assertEqual(
-                    '1 of 2 volume transfer requests failed ' 'to delete',
+                    '1 of 2 volume transfer requests failed to delete',
                     str(e),
                 )
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/fakes.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/fakes.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/fakes.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/fakes.py	2025-07-07 22:41:56.000000000 +0000
@@ -129,14 +129,8 @@ class TestVolume(
 
         # avoid circular imports by defining this manually rather than using
         # openstackclient.tests.unit.compute.v2.fakes.FakeClientMixin
-        # TODO(stephenfin): Rename to 'compute_client' once all commands are
-        # migrated to SDK
-        self.app.client_manager.sdk_connection.compute = mock.Mock(
-            _compute_proxy.Proxy
-        )
-        self.compute_sdk_client = (
-            self.app.client_manager.sdk_connection.compute
-        )
+        self.app.client_manager.compute = mock.Mock(_compute_proxy.Proxy)
+        self.compute_client = self.app.client_manager.compute
 
         # avoid circular imports by defining this manually rather than using
         # openstackclient.tests.unit.image.v2.fakes.FakeClientMixin
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py	2025-07-07 22:41:56.000000000 +0000
@@ -10,9 +10,10 @@
 #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #   License for the specific language governing permissions and limitations
 #   under the License.
-#
 
 import ddt
+from openstack.block_storage.v3 import service as _service
+from openstack.test import fakes as sdk_fakes
 from osc_lib import exceptions
 
 from openstackclient.tests.unit import utils as tests_utils
@@ -20,24 +21,17 @@ from openstackclient.tests.unit.volume.v
 from openstackclient.volume.v3 import block_storage_log_level as service
 
 
-class TestService(volume_fakes.TestVolume):
+class TestBlockStorageLogLevelList(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        # Get a shortcut to the ServiceManager Mock
-        self.service_mock = self.volume_client.services
-        self.service_mock.reset_mock()
-
-
-class TestBlockStorageLogLevelList(TestService):
-    service_log = volume_fakes.create_service_log_level_entry()
-
-    def setUp(self):
-        super().setUp()
-
-        self.service_mock.get_log_levels.return_value = [self.service_log]
+        self.log_level = sdk_fakes.generate_fake_resource(
+            _service.LogLevel, binary='cinder-scheduler'
+        )
+        self.volume_sdk_client.get_service_log_levels.return_value = [
+            self.log_level
+        ]
 
-        # Get the command object to test
         self.cmd = service.BlockStorageLogLevelList(self.app, None)
 
     def test_block_storage_log_level_list(self):
@@ -45,16 +39,16 @@ class TestBlockStorageLogLevelList(TestS
 
         arglist = [
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
-            self.service_log.binary,
+            self.log_level.binary,
             '--log-prefix',
-            self.service_log.prefix,
+            'cinder.',
         ]
         verifylist = [
-            ('host', self.service_log.host),
-            ('service', self.service_log.binary),
-            ('log_prefix', self.service_log.prefix),
+            ('host', self.log_level.host),
+            ('service', self.log_level.binary),
+            ('log_prefix', 'cinder.'),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -66,40 +60,35 @@ class TestBlockStorageLogLevelList(TestS
             'Prefix',
             'Level',
         ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
-        datalist = (
+        datalist = tuple(
             (
-                self.service_log.binary,
-                self.service_log.host,
-                self.service_log.prefix,
-                self.service_log.level,
-            ),
+                self.log_level.binary,
+                self.log_level.host,
+                prefix,
+                level,
+            )
+            for prefix, level in self.log_level.levels.values()
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
 
-        # checking if proper call was made to get log level of services
-        self.service_mock.get_log_levels.assert_called_with(
-            server=self.service_log.host,
-            binary=self.service_log.binary,
-            prefix=self.service_log.prefix,
+        self.volume_sdk_client.get_service_log_levels.assert_called_with(
+            server=self.log_level.host,
+            binary=self.log_level.binary,
+            prefix='cinder.',
         )
 
     def test_block_storage_log_level_list_pre_332(self):
         arglist = [
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
             'cinder-api',
             '--log-prefix',
             'cinder_test.api.common',
         ]
         verifylist = [
-            ('host', self.service_log.host),
+            ('host', self.log_level.host),
             ('service', 'cinder-api'),
             ('log_prefix', 'cinder_test.api.common'),
         ]
@@ -117,14 +106,14 @@ class TestBlockStorageLogLevelList(TestS
 
         arglist = [
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
             'nova-api',
             '--log-prefix',
             'cinder_test.api.common',
         ]
         verifylist = [
-            ('host', self.service_log.host),
+            ('host', self.log_level.host),
             ('service', 'nova-api'),
             ('log_prefix', 'cinder_test.api.common'),
         ]
@@ -139,13 +128,15 @@ class TestBlockStorageLogLevelList(TestS
 
 
 @ddt.ddt
-class TestBlockStorageLogLevelSet(TestService):
-    service_log = volume_fakes.create_service_log_level_entry()
-
+class TestBlockStorageLogLevelSet(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        # Get the command object to test
+        self.log_level = sdk_fakes.generate_fake_resource(
+            _service.LogLevel, binary='cinder-api'
+        )
+        self.volume_sdk_client.set_service_log_levels.return_value = None
+
         self.cmd = service.BlockStorageLogLevelSet(self.app, None)
 
     def test_block_storage_log_level_set(self):
@@ -154,45 +145,45 @@ class TestBlockStorageLogLevelSet(TestSe
         arglist = [
             'ERROR',
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
-            self.service_log.binary,
+            self.log_level.binary,
             '--log-prefix',
-            self.service_log.prefix,
+            'cinder.api.common',
         ]
         verifylist = [
             ('level', 'ERROR'),
-            ('host', self.service_log.host),
-            ('service', self.service_log.binary),
-            ('log_prefix', self.service_log.prefix),
+            ('host', self.log_level.host),
+            ('service', self.log_level.binary),
+            ('log_prefix', 'cinder.api.common'),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.cmd.take_action(parsed_args)
+        ret = self.cmd.take_action(parsed_args)
 
-        # checking if proper call was made to set log level of services
-        self.service_mock.set_log_levels.assert_called_with(
+        self.assertIsNone(ret)
+        self.volume_sdk_client.set_service_log_levels.assert_called_with(
             level='ERROR',
-            server=self.service_log.host,
-            binary=self.service_log.binary,
-            prefix=self.service_log.prefix,
+            server=self.log_level.host,
+            binary=self.log_level.binary,
+            prefix='cinder.api.common',
         )
 
     def test_block_storage_log_level_set_pre_332(self):
         arglist = [
             'ERROR',
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
             'cinder-api',
             '--log-prefix',
-            'cinder_test.api.common',
+            'cinder.api.common',
         ]
         verifylist = [
             ('level', 'ERROR'),
-            ('host', self.service_log.host),
+            ('host', self.log_level.host),
             ('service', 'cinder-api'),
-            ('log_prefix', 'cinder_test.api.common'),
+            ('log_prefix', 'cinder.api.common'),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -209,7 +200,7 @@ class TestBlockStorageLogLevelSet(TestSe
         arglist = [
             'ERROR',
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
             'nova-api',
             '--log-prefix',
@@ -217,7 +208,7 @@ class TestBlockStorageLogLevelSet(TestSe
         ]
         verifylist = [
             ('level', 'ERROR'),
-            ('host', self.service_log.host),
+            ('host', self.log_level.host),
             ('service', 'nova-api'),
             ('log_prefix', 'cinder.api.common'),
         ]
@@ -237,7 +228,7 @@ class TestBlockStorageLogLevelSet(TestSe
         arglist = [
             log_level,
             '--host',
-            self.service_log.host,
+            self.log_level.host,
             '--service',
             'cinder-api',
             '--log-prefix',
@@ -245,7 +236,7 @@ class TestBlockStorageLogLevelSet(TestSe
         ]
         verifylist = [
             ('level', log_level.upper()),
-            ('host', self.service_log.host),
+            ('host', self.log_level.host),
             ('service', 'cinder-api'),
             ('log_prefix', 'cinder.api.common'),
         ]
@@ -263,10 +254,9 @@ class TestBlockStorageLogLevelSet(TestSe
 
             self.cmd.take_action(parsed_args)
 
-            # checking if proper call was made to set log level of services
-            self.service_mock.set_log_levels.assert_called_with(
+            self.volume_sdk_client.set_service_log_levels.assert_called_with(
                 level=log_level.upper(),
-                server=self.service_log.host,
-                binary=self.service_log.binary,
-                prefix=self.service_log.prefix,
+                server=self.log_level.host,
+                binary=self.log_level.binary,
+                prefix='cinder.api.common',
             )
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_service.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_service.py	2025-07-07 22:41:56.000000000 +0000
@@ -12,108 +12,83 @@
 #   under the License.
 #
 
-from cinderclient import api_versions
+from unittest import mock
+
+from openstack.block_storage.v3 import service as _service
+from openstack.test import fakes as sdk_fakes
+from osc_lib import exceptions
 
 from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
 from openstackclient.volume.v3 import service
 
 
-class TestService(volume_fakes.TestVolume):
-    def setUp(self):
-        super().setUp()
-
-        # Get a shortcut to the ServiceManager Mock
-        self.service_mock = self.volume_client.services
-        self.service_mock.reset_mock()
-
-
-class TestServiceList(TestService):
-    # The service to be listed
-    services = volume_fakes.create_one_service()
-
+class TestServiceList(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.service_mock.list.return_value = [self.services]
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.volume_sdk_client.services.return_value = [self.service]
 
-        # Get the command object to test
         self.cmd = service.ListService(self.app, None)
 
     def test_service_list(self):
         arglist = [
             '--host',
-            self.services.host,
+            self.service.host,
             '--service',
-            self.services.binary,
+            self.service.binary,
         ]
         verifylist = [
-            ('host', self.services.host),
-            ('service', self.services.binary),
+            ('host', self.service.host),
+            ('service', self.service.binary),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        expected_columns = [
+        expected_columns = (
             'Binary',
             'Host',
             'Zone',
             'Status',
             'State',
             'Updated At',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
+        )
         datalist = (
             (
-                self.services.binary,
-                self.services.host,
-                self.services.zone,
-                self.services.status,
-                self.services.state,
-                self.services.updated_at,
+                self.service.binary,
+                self.service.host,
+                self.service.availability_zone,
+                self.service.status,
+                self.service.state,
+                self.service.updated_at,
             ),
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
-
-        # checking if proper call was made to list services
-        self.service_mock.list.assert_called_with(
-            self.services.host,
-            self.services.binary,
+        self.volume_sdk_client.services.assert_called_with(
+            host=self.service.host,
+            binary=self.service.binary,
         )
 
-        # checking if prohibited columns are present in output
-        self.assertNotIn("Disabled Reason", columns)
-        self.assertNotIn(self.services.disabled_reason, tuple(data))
-
     def test_service_list_with_long_option(self):
         arglist = [
             '--host',
-            self.services.host,
+            self.service.host,
             '--service',
-            self.services.binary,
+            self.service.binary,
             '--long',
         ]
         verifylist = [
-            ('host', self.services.host),
-            ('service', self.services.binary),
+            ('host', self.service.host),
+            ('service', self.service.binary),
             ('long', True),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        expected_columns = [
+        expected_columns = (
             'Binary',
             'Host',
             'Zone',
@@ -121,55 +96,43 @@ class TestServiceList(TestService):
             'State',
             'Updated At',
             'Disabled Reason',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
+        )
         datalist = (
             (
-                self.services.binary,
-                self.services.host,
-                self.services.zone,
-                self.services.status,
-                self.services.state,
-                self.services.updated_at,
-                self.services.disabled_reason,
+                self.service.binary,
+                self.service.host,
+                self.service.availability_zone,
+                self.service.status,
+                self.service.state,
+                self.service.updated_at,
+                self.service.disabled_reason,
             ),
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
-
-        self.service_mock.list.assert_called_with(
-            self.services.host,
-            self.services.binary,
+        self.volume_sdk_client.services.assert_called_with(
+            host=self.service.host,
+            binary=self.service.binary,
         )
 
     def test_service_list_with_cluster(self):
-        self.volume_client.api_version = api_versions.APIVersion('3.7')
-        cluster = {'cluster': 'fake-cluster'}
-        cluster_service = volume_fakes.create_one_service(attrs=cluster)
-        self.service_mock.list.return_value = [cluster_service]
+        self.set_volume_api_version('3.7')
 
         arglist = [
             '--host',
-            cluster_service.host,
+            self.service.host,
             '--service',
-            cluster_service.binary,
+            self.service.binary,
         ]
         verifylist = [
-            ('host', cluster_service.host),
-            ('service', cluster_service.binary),
+            ('host', self.service.host),
+            ('service', self.service.binary),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        expected_columns = [
+        expected_columns = (
             'Binary',
             'Host',
             'Zone',
@@ -177,60 +140,43 @@ class TestServiceList(TestService):
             'State',
             'Updated At',
             'Cluster',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
+        )
         datalist = (
             (
-                cluster_service.binary,
-                cluster_service.host,
-                cluster_service.zone,
-                cluster_service.status,
-                cluster_service.state,
-                cluster_service.updated_at,
-                cluster_service.cluster,
+                self.service.binary,
+                self.service.host,
+                self.service.availability_zone,
+                self.service.status,
+                self.service.state,
+                self.service.updated_at,
+                self.service.cluster,
             ),
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
-
-        # checking if proper call was made to list services
-        self.service_mock.list.assert_called_with(
-            cluster_service.host,
-            cluster_service.binary,
+        self.volume_sdk_client.services.assert_called_with(
+            host=self.service.host,
+            binary=self.service.binary,
         )
 
-        # checking if prohibited columns are present in output
-        self.assertNotIn("Disabled Reason", columns)
-        self.assertNotIn(cluster_service.disabled_reason, tuple(data))
-
     def test_service_list_with_backend_state(self):
-        self.volume_client.api_version = api_versions.APIVersion('3.49')
-        backend_state = {'cluster': 'fake-cluster', 'backend_state': 'up'}
-        backend_service = volume_fakes.create_one_service(attrs=backend_state)
-        self.service_mock.list.return_value = [backend_service]
+        self.set_volume_api_version('3.49')
 
         arglist = [
             '--host',
-            backend_service.host,
+            self.service.host,
             '--service',
-            backend_service.binary,
+            self.service.binary,
         ]
         verifylist = [
-            ('host', backend_service.host),
-            ('service', backend_service.binary),
+            ('host', self.service.host),
+            ('service', self.service.binary),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class Lister in cliff, abstract method take_action()
-        # returns a tuple containing the column names and an iterable
-        # containing the data to be listed.
         columns, data = self.cmd.take_action(parsed_args)
 
-        expected_columns = [
+        expected_columns = (
             'Binary',
             'Host',
             'Zone',
@@ -239,33 +185,167 @@ class TestServiceList(TestService):
             'Updated At',
             'Cluster',
             'Backend State',
-        ]
-
-        # confirming if all expected columns are present in the result.
-        self.assertEqual(expected_columns, columns)
-
+        )
         datalist = (
             (
-                backend_service.binary,
-                backend_service.host,
-                backend_service.zone,
-                backend_service.status,
-                backend_service.state,
-                backend_service.updated_at,
-                backend_service.cluster,
-                backend_service.backend_state,
+                self.service.binary,
+                self.service.host,
+                self.service.availability_zone,
+                self.service.status,
+                self.service.state,
+                self.service.updated_at,
+                self.service.cluster,
+                self.service.backend_state,
             ),
         )
-
-        # confirming if all expected values are present in the result.
+        self.assertEqual(expected_columns, columns)
         self.assertEqual(datalist, tuple(data))
+        self.volume_sdk_client.services.assert_called_with(
+            host=self.service.host,
+            binary=self.service.binary,
+        )
+
+
+class TestServiceSet(volume_fakes.TestVolume):
+    def setUp(self):
+        super().setUp()
+
+        self.service = sdk_fakes.generate_fake_resource(_service.Service)
+        self.service.enable = mock.Mock(autospec=True)
+        self.service.disable = mock.Mock(autospec=True)
+        self.volume_sdk_client.find_service.return_value = self.service
 
-        # checking if proper call was made to list services
-        self.service_mock.list.assert_called_with(
-            backend_service.host,
-            backend_service.binary,
+        self.cmd = service.SetService(self.app, None)
+
+    def test_service_set_nothing(self):
+        arglist = [
+            self.service.host,
+            self.service.binary,
+        ]
+        verifylist = [
+            ('host', self.service.host),
+            ('service', self.service.binary),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        result = self.cmd.take_action(parsed_args)
+
+        self.service.enable.assert_not_called()
+        self.service.disable.assert_not_called()
+        self.assertIsNone(result)
+
+    def test_service_set_enable(self):
+        arglist = [
+            '--enable',
+            self.service.host,
+            self.service.binary,
+        ]
+        verifylist = [
+            ('enable', True),
+            ('host', self.service.host),
+            ('service', self.service.binary),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.service.enable.assert_called_with(self.volume_sdk_client)
+        self.service.disable.assert_not_called()
+        self.assertIsNone(result)
+
+    def test_service_set_disable(self):
+        arglist = [
+            '--disable',
+            self.service.host,
+            self.service.binary,
+        ]
+        verifylist = [
+            ('disable', True),
+            ('host', self.service.host),
+            ('service', self.service.binary),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.service.enable.assert_not_called()
+        self.service.disable.assert_called_with(
+            self.volume_sdk_client, reason=None
         )
+        self.assertIsNone(result)
+
+    def test_service_set_disable_with_reason(self):
+        reason = 'earthquake'
+        arglist = [
+            '--disable',
+            '--disable-reason',
+            reason,
+            self.service.host,
+            self.service.binary,
+        ]
+        verifylist = [
+            ('disable', True),
+            ('disable_reason', reason),
+            ('host', self.service.host),
+            ('service', self.service.binary),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.service.enable.assert_not_called()
+        self.service.disable.assert_called_with(
+            self.volume_sdk_client, reason=reason
+        )
+        self.assertIsNone(result)
+
+    def test_service_set_only_with_disable_reason(self):
+        reason = 'earthquake'
+        arglist = [
+            '--disable-reason',
+            reason,
+            self.service.host,
+            self.service.binary,
+        ]
+        verifylist = [
+            ('disable_reason', reason),
+            ('host', self.service.host),
+            ('service', self.service.binary),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        try:
+            self.cmd.take_action(parsed_args)
+            self.fail("CommandError should be raised.")
+        except exceptions.CommandError as e:
+            self.assertEqual(
+                "Cannot specify option --disable-reason without "
+                "--disable specified.",
+                str(e),
+            )
+
+    def test_service_set_enable_with_disable_reason(self):
+        reason = 'earthquake'
+        arglist = [
+            '--enable',
+            '--disable-reason',
+            reason,
+            self.service.host,
+            self.service.binary,
+        ]
+        verifylist = [
+            ('enable', True),
+            ('disable_reason', reason),
+            ('host', self.service.host),
+            ('service', self.service.binary),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # checking if prohibited columns are present in output
-        self.assertNotIn("Disabled Reason", columns)
-        self.assertNotIn(backend_service.disabled_reason, tuple(data))
+        try:
+            self.cmd.take_action(parsed_args)
+            self.fail("CommandError should be raised.")
+        except exceptions.CommandError as e:
+            self.assertEqual(
+                "Cannot specify option --disable-reason without "
+                "--disable specified.",
+                str(e),
+            )
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@ from unittest import mock
 from openstack.block_storage.v3 import block_storage_summary as _summary
 from openstack.block_storage.v3 import snapshot as _snapshot
 from openstack.block_storage.v3 import volume as _volume
+from openstack import exceptions as sdk_exceptions
 from openstack.test import fakes as sdk_fakes
 from osc_lib.cli import format_columns
 from osc_lib import exceptions
@@ -179,7 +180,7 @@ class TestVolumeCreateLegacy(volume_fake
             self.new_volume.name,
         ]
         verifylist = [
-            ('property', {'Alpha': 'a', 'Beta': 'b'}),
+            ('properties', {'Alpha': 'a', 'Beta': 'b'}),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -440,9 +441,7 @@ class TestVolumeCreateLegacy(volume_fake
         ]
         verifylist = [
             ('bootable', True),
-            ('non_bootable', False),
             ('read_only', True),
-            ('read_write', False),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -486,9 +485,7 @@ class TestVolumeCreateLegacy(volume_fake
         ]
         verifylist = [
             ('bootable', False),
-            ('non_bootable', True),
             ('read_only', False),
-            ('read_write', True),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -541,9 +538,7 @@ class TestVolumeCreateLegacy(volume_fake
         ]
         verifylist = [
             ('bootable', True),
-            ('non_bootable', False),
             ('read_only', True),
-            ('read_write', False),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -593,9 +588,7 @@ class TestVolumeCreateLegacy(volume_fake
         ]
         verifylist = [
             ('bootable', False),
-            ('non_bootable', True),
             ('read_only', True),
-            ('read_write', False),
             ('size', self.new_volume.size),
             ('name', self.new_volume.name),
         ]
@@ -838,7 +831,7 @@ class TestVolumeCreate(volume_fakes.Test
             description=parsed_args.description,
             volume_type=parsed_args.type,
             availability_zone=parsed_args.availability_zone,
-            metadata=parsed_args.property,
+            metadata=parsed_args.properties,
             bootable=parsed_args.bootable,
             cluster=getattr(parsed_args, 'cluster', None),
         )
@@ -962,16 +955,17 @@ class TestVolumeCreate(volume_fakes.Test
         )
 
 
-class TestVolumeDeleteLegacy(volume_fakes.TestVolume):
+class TestVolumeDelete(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
         self.volumes_mock = self.volume_client.volumes
         self.volumes_mock.reset_mock()
 
-        self.volumes_mock.delete.return_value = None
-        self.volumes = volume_fakes.create_volumes(count=1)
-        self.volumes_mock.get = volume_fakes.get_volumes(self.volumes, 0)
+        self.volumes = list(sdk_fakes.generate_fake_resources(_volume.Volume))
+        self.volume_sdk_client.find_volume.side_effect = self.volumes
+        self.volume_sdk_client.delete_volume.return_value = None
+        self.volume_sdk_client.unmanage_volume.return_value = None
 
         # Get the command object to mock
         self.cmd = volume.DeleteVolume(self.app, None)
@@ -986,11 +980,14 @@ class TestVolumeDeleteLegacy(volume_fake
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.volumes_mock.delete.assert_called_once_with(
-            self.volumes[0].id, cascade=False
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_called_once_with(
+            self.volumes[0].id, cascade=False, force=False
         )
-        self.assertIsNone(result)
 
     def test_volume_delete_multi_volumes(self):
         arglist = [v.id for v in self.volumes]
@@ -1002,12 +999,21 @@ class TestVolumeDeleteLegacy(volume_fake
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-
-        calls = [mock.call(v.id, cascade=False) for v in self.volumes]
-        self.volumes_mock.delete.assert_has_calls(calls)
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_volume.assert_has_calls(
+            [mock.call(v.id, ignore_missing=False) for v in self.volumes]
+        )
+        self.volume_sdk_client.delete_volume.assert_has_calls(
+            [mock.call(v.id, cascade=False, force=False) for v in self.volumes]
+        )
+
     def test_volume_delete_multi_volumes_with_exception(self):
+        self.volume_sdk_client.find_volume.side_effect = [
+            self.volumes[0],
+            sdk_exceptions.NotFoundException(),
+        ]
+
         arglist = [
             self.volumes[0].id,
             'unexist_volume',
@@ -1015,27 +1021,28 @@ class TestVolumeDeleteLegacy(volume_fake
         verifylist = [
             ('force', False),
             ('purge', False),
-            ('volumes', arglist),
+            ('volumes', [self.volumes[0].id, 'unexist_volume']),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        find_mock_result = [self.volumes[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual('1 of 2 volumes failed to delete.', str(e))
-
-            find_mock.assert_any_call(self.volumes_mock, self.volumes[0].id)
-            find_mock.assert_any_call(self.volumes_mock, 'unexist_volume')
-
-            self.assertEqual(2, find_mock.call_count)
-            self.volumes_mock.delete.assert_called_once_with(
-                self.volumes[0].id, cascade=False
-            )
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+        self.assertEqual('1 of 2 volumes failed to delete.', str(exc))
+
+        self.volume_sdk_client.find_volume.assert_has_calls(
+            [
+                mock.call(self.volumes[0].id, ignore_missing=False),
+                mock.call('unexist_volume', ignore_missing=False),
+            ]
+        )
+        self.volume_sdk_client.delete_volume.assert_has_calls(
+            [
+                mock.call(self.volumes[0].id, cascade=False, force=False),
+            ]
+        )
 
     def test_volume_delete_with_purge(self):
         arglist = [
@@ -1050,11 +1057,14 @@ class TestVolumeDeleteLegacy(volume_fake
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.volumes_mock.delete.assert_called_once_with(
-            self.volumes[0].id, cascade=True
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_called_once_with(
+            self.volumes[0].id, cascade=True, force=False
         )
-        self.assertIsNone(result)
 
     def test_volume_delete_with_force(self):
         arglist = [
@@ -1069,49 +1079,38 @@ class TestVolumeDeleteLegacy(volume_fake
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-
-        self.volumes_mock.force_delete.assert_called_once_with(
-            self.volumes[0].id
-        )
         self.assertIsNone(result)
 
-
-class TestVolumeDelete(volume_fakes.TestVolume):
-    def setUp(self):
-        super().setUp()
-
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-        self.volume_sdk_client.unmanage_volume.return_value = None
-
-        # Get the command object to mock
-        self.cmd = volume.DeleteVolume(self.app, None)
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_called_once_with(
+            self.volumes[0].id, cascade=False, force=True
+        )
 
     def test_volume_delete_remote(self):
-        vol = sdk_fakes.generate_fake_resource(_volume.Volume, **{'size': 1})
-        self.volumes_mock.get.return_value = vol
-
-        arglist = ['--remote', vol.id]
+        arglist = ['--remote', self.volumes[0].id]
         verifylist = [
             ("remote", True),
             ("force", False),
             ("purge", False),
-            ("volumes", [vol.id]),
+            ("volumes", [self.volumes[0].id]),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-
-        self.volume_sdk_client.unmanage_volume.assert_called_once_with(vol.id)
         self.assertIsNone(result)
 
-    def test_volume_delete_multi_volumes_remote(self):
-        volumes = sdk_fakes.generate_fake_resources(
-            _volume.Volume, count=3, attrs={'size': 1}
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.volumes[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_volume.assert_not_called()
+        self.volume_sdk_client.unmanage_volume.assert_called_once_with(
+            self.volumes[0].id
         )
 
-        arglist = ['--remote']
-        arglist += [v.id for v in volumes]
+    def test_volume_delete_multi_volumes_remote(self):
+        arglist = ['--remote'] + [v.id for v in self.volumes]
         verifylist = [
             ('remote', True),
             ('force', False),
@@ -1121,24 +1120,27 @@ class TestVolumeDelete(volume_fakes.Test
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-
-        calls = [mock.call(v.id) for v in volumes]
-        self.volume_sdk_client.unmanage_volume.assert_has_calls(calls)
         self.assertIsNone(result)
 
-    def test_volume_delete_remote_with_purge(self):
-        vol = sdk_fakes.generate_fake_resource(_volume.Volume, **{'size': 1})
+        self.volume_sdk_client.find_volume.assert_has_calls(
+            [mock.call(v.id, ignore_missing=False) for v in self.volumes]
+        )
+        self.volume_sdk_client.delete_volume.assert_not_called()
+        self.volume_sdk_client.unmanage_volume.assert_has_calls(
+            [mock.call(v.id) for v in self.volumes]
+        )
 
+    def test_volume_delete_remote_with_purge(self):
         arglist = [
             '--remote',
             '--purge',
-            vol.id,
+            self.volumes[0].id,
         ]
         verifylist = [
             ('remote', True),
             ('force', False),
             ('purge', True),
-            ('volumes', [vol.id]),
+            ('volumes', [self.volumes[0].id]),
         ]
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1151,19 +1153,21 @@ class TestVolumeDelete(volume_fakes.Test
             str(exc),
         )
 
-    def test_volume_delete_remote_with_force(self):
-        vol = sdk_fakes.generate_fake_resource(_volume.Volume, **{'size': 1})
+        self.volume_sdk_client.find_volume.assert_not_called()
+        self.volume_sdk_client.delete_volume.assert_not_called()
+        self.volume_sdk_client.unmanage_volume.assert_not_called()
 
+    def test_volume_delete_remote_with_force(self):
         arglist = [
             '--remote',
             '--force',
-            vol.id,
+            self.volumes[0].id,
         ]
         verifylist = [
             ('remote', True),
             ('force', True),
             ('purge', False),
-            ('volumes', [vol.id]),
+            ('volumes', [self.volumes[0].id]),
         ]
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1176,6 +1180,10 @@ class TestVolumeDelete(volume_fakes.Test
             str(exc),
         )
 
+        self.volume_sdk_client.find_volume.assert_not_called()
+        self.volume_sdk_client.delete_volume.assert_not_called()
+        self.volume_sdk_client.unmanage_volume.assert_not_called()
+
 
 class TestVolumeList(volume_fakes.TestVolume):
     project = identity_fakes.FakeProject.create_one_project()
@@ -1231,6 +1239,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1274,6 +1283,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1320,6 +1330,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1363,6 +1374,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': self.user.id,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1408,6 +1420,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': self.user.id,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1451,6 +1464,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': self.mock_volume.name,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1494,6 +1508,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': self.mock_volume.status,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1536,6 +1551,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1579,6 +1595,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1652,6 +1669,7 @@ class TestVolumeList(volume_fakes.TestVo
                 'user_id': None,
                 'name': None,
                 'all_tenants': False,
+                'metadata': None,
             },
         )
         self.assertCountEqual(datalist, tuple(data))
@@ -1696,6 +1714,7 @@ class TestVolumeList(volume_fakes.TestVo
             'user_id': None,
             'name': None,
             'status': None,
+            'metadata': None,
         }
         self.volumes_mock.list.assert_called_once_with(
             search_opts=search_opts,
@@ -1815,16 +1834,16 @@ class TestVolumeSet(volume_fakes.TestVol
             self.new_volume.id,
         ]
         verifylist = [
-            ('property', {'a': 'b', 'c': 'd'}),
+            ('properties', {'a': 'b', 'c': 'd'}),
+            ('read_only', None),
+            ('bootable', None),
             ('volume', self.new_volume.id),
-            ('bootable', False),
-            ('non_bootable', False),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         self.cmd.take_action(parsed_args)
         self.volumes_mock.set_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.property
+            self.new_volume.id, parsed_args.properties
         )
 
     def test_volume_set_image_property(self):
@@ -1836,10 +1855,10 @@ class TestVolumeSet(volume_fakes.TestVol
             self.new_volume.id,
         ]
         verifylist = [
-            ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
+            ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
+            ('read_only', None),
+            ('bootable', None),
             ('volume', self.new_volume.id),
-            ('bootable', False),
-            ('non_bootable', False),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -1847,15 +1866,15 @@ class TestVolumeSet(volume_fakes.TestVol
         # returns nothing
         self.cmd.take_action(parsed_args)
         self.volumes_mock.set_image_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.image_property
+            self.new_volume.id, parsed_args.image_properties
         )
 
     def test_volume_set_state(self):
         arglist = ['--state', 'error', self.new_volume.id]
         verifylist = [
-            ('read_only', False),
-            ('read_write', False),
             ('state', 'error'),
+            ('read_only', None),
+            ('bootable', None),
             ('volume', self.new_volume.id),
         ]
 
@@ -1919,36 +1938,40 @@ class TestVolumeSet(volume_fakes.TestVol
 
     def test_volume_set_bootable(self):
         arglist = [
-            ['--bootable', self.new_volume.id],
-            ['--non-bootable', self.new_volume.id],
+            '--bootable',
+            self.new_volume.id,
         ]
         verifylist = [
-            [
-                ('bootable', True),
-                ('non_bootable', False),
-                ('volume', self.new_volume.id),
-            ],
-            [
-                ('bootable', False),
-                ('non_bootable', True),
-                ('volume', self.new_volume.id),
-            ],
-        ]
-        for index in range(len(arglist)):
-            parsed_args = self.check_parser(
-                self.cmd, arglist[index], verifylist[index]
-            )
+            ('bootable', True),
+            ('volume', self.new_volume.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-            self.cmd.take_action(parsed_args)
-            self.volumes_mock.set_bootable.assert_called_with(
-                self.new_volume.id, verifylist[index][0][1]
-            )
+        self.cmd.take_action(parsed_args)
+        self.volumes_mock.set_bootable.assert_called_with(
+            self.new_volume.id, verifylist[0][1]
+        )
+
+    def test_volume_set_non_bootable(self):
+        arglist = [
+            '--non-bootable',
+            self.new_volume.id,
+        ]
+        verifylist = [
+            ('bootable', False),
+            ('volume', self.new_volume.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+        self.volumes_mock.set_bootable.assert_called_with(
+            self.new_volume.id, verifylist[0][1]
+        )
 
     def test_volume_set_readonly(self):
         arglist = ['--read-only', self.new_volume.id]
         verifylist = [
             ('read_only', True),
-            ('read_write', False),
             ('volume', self.new_volume.id),
         ]
 
@@ -1964,7 +1987,6 @@ class TestVolumeSet(volume_fakes.TestVol
         arglist = ['--read-write', self.new_volume.id]
         verifylist = [
             ('read_only', False),
-            ('read_write', True),
             ('volume', self.new_volume.id),
         ]
 
@@ -2027,7 +2049,7 @@ class TestVolumeSet(volume_fakes.TestVol
         result = self.cmd.take_action(parsed_args)
         self.volumes_mock.retype.assert_not_called()
         mock_warning.assert_called_with(
-            "'--retype-policy' option will " "not work without '--type' option"
+            "'--retype-policy' option will not work without '--type' option"
         )
         self.assertIsNone(result)
 
@@ -2100,7 +2122,7 @@ class TestVolumeUnset(volume_fakes.TestV
             self.new_volume.id,
         ]
         verifylist = [
-            ('image_property', {'Alpha': 'a', 'Beta': 'b'}),
+            ('image_properties', {'Alpha': 'a', 'Beta': 'b'}),
             ('volume', self.new_volume.id),
         ]
         parsed_args = self.check_parser(self.cmd_set, arglist, verifylist)
@@ -2116,7 +2138,7 @@ class TestVolumeUnset(volume_fakes.TestV
             self.new_volume.id,
         ]
         verifylist_unset = [
-            ('image_property', ['Alpha']),
+            ('image_properties', ['Alpha']),
             ('volume', self.new_volume.id),
         ]
         parsed_args_unset = self.check_parser(
@@ -2128,7 +2150,7 @@ class TestVolumeUnset(volume_fakes.TestV
         self.cmd_unset.take_action(parsed_args_unset)
 
         self.volumes_mock.delete_image_metadata.assert_called_with(
-            self.new_volume.id, parsed_args_unset.image_property
+            self.new_volume.id, parsed_args_unset.image_properties
         )
 
     def test_volume_unset_image_property_fail(self):
@@ -2143,8 +2165,8 @@ class TestVolumeUnset(volume_fakes.TestV
             self.new_volume.id,
         ]
         verifylist = [
-            ('image_property', ['Alpha']),
-            ('property', ['Beta']),
+            ('image_properties', ['Alpha']),
+            ('properties', ['Beta']),
             ('volume', self.new_volume.id),
         ]
         parsed_args = self.check_parser(self.cmd_unset, arglist, verifylist)
@@ -2157,10 +2179,10 @@ class TestVolumeUnset(volume_fakes.TestV
                 'One or more of the unset operations failed', str(e)
             )
         self.volumes_mock.delete_image_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.image_property
+            self.new_volume.id, parsed_args.image_properties
         )
         self.volumes_mock.delete_metadata.assert_called_with(
-            self.new_volume.id, parsed_args.property
+            self.new_volume.id, parsed_args.properties
         )
 
 
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_attachment.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_attachment.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_attachment.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_attachment.py	2025-07-07 22:41:56.000000000 +0000
@@ -28,7 +28,7 @@ class TestVolumeAttachment(volume_fakes.
 
 class TestVolumeAttachmentCreate(TestVolumeAttachment):
     volume = volume_fakes.create_one_volume()
-    server = compute_fakes.create_one_sdk_server()
+    server = compute_fakes.create_one_server()
     volume_attachment = volume_fakes.create_one_volume_attachment(
         attrs={'instance': server.id, 'volume_id': volume.id},
     )
@@ -61,7 +61,7 @@ class TestVolumeAttachmentCreate(TestVol
         self.volume_sdk_client.create_attachment.return_value = (
             self.volume_attachment.to_dict()
         )
-        self.compute_sdk_client.find_server.return_value = self.server
+        self.compute_client.find_server.return_value = self.server
 
         self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None)
 
@@ -92,7 +92,7 @@ class TestVolumeAttachmentCreate(TestVol
         self.volume_sdk_client.find_volume.assert_called_once_with(
             self.volume.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.volume_sdk_client.create_attachment.assert_called_once_with(
@@ -159,7 +159,7 @@ class TestVolumeAttachmentCreate(TestVol
         self.volume_sdk_client.find_volume.assert_called_once_with(
             self.volume.id, ignore_missing=False
         )
-        self.compute_sdk_client.find_server.assert_called_once_with(
+        self.compute_client.find_server.assert_called_once_with(
             self.server.id, ignore_missing=False
         )
         self.volume_sdk_client.create_attachment.assert_called_once_with(
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_backup.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_backup.py	2025-07-07 22:41:56.000000000 +0000
@@ -11,91 +11,83 @@
 #   License for the specific language governing permissions and limitations
 #   under the License.
 
-from unittest.mock import call
+from unittest import mock
 
+from openstack.block_storage.v3 import backup as _backup
+from openstack.block_storage.v3 import snapshot as _snapshot
+from openstack.block_storage.v3 import volume as _volume
+from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
 from osc_lib import exceptions
 
 from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
 from openstackclient.volume.v3 import volume_backup
 
 
-class TestBackupLegacy(volume_fakes.TestVolume):
-    def setUp(self):
-        super().setUp()
-
-        self.backups_mock = self.volume_client.backups
-        self.backups_mock.reset_mock()
-        self.volumes_mock = self.volume_client.volumes
-        self.volumes_mock.reset_mock()
-        self.snapshots_mock = self.volume_client.volume_snapshots
-        self.snapshots_mock.reset_mock()
-        self.restores_mock = self.volume_client.restores
-        self.restores_mock.reset_mock()
-
-
 class TestBackupCreate(volume_fakes.TestVolume):
-    volume = volume_fakes.create_one_volume()
-    snapshot = volume_fakes.create_one_snapshot()
-    new_backup = volume_fakes.create_one_backup(
-        attrs={'volume_id': volume.id, 'snapshot_id': snapshot.id}
-    )
-
     columns = (
         'id',
         'name',
         'volume_id',
     )
-    data = (
-        new_backup.id,
-        new_backup.name,
-        new_backup.volume_id,
-    )
 
     def setUp(self):
         super().setUp()
 
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
         self.volume_sdk_client.find_volume.return_value = self.volume
+        self.snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
         self.volume_sdk_client.find_snapshot.return_value = self.snapshot
-        self.volume_sdk_client.create_backup.return_value = self.new_backup
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup,
+            volume_id=self.volume.id,
+            snapshot_id=self.snapshot.id,
+        )
+        self.volume_sdk_client.create_backup.return_value = self.backup
+
+        self.data = (
+            self.backup.id,
+            self.backup.name,
+            self.backup.volume_id,
+        )
 
-        # Get the command object to test
         self.cmd = volume_backup.CreateVolumeBackup(self.app, None)
 
     def test_backup_create(self):
         arglist = [
             "--name",
-            self.new_backup.name,
+            self.backup.name,
             "--description",
-            self.new_backup.description,
+            self.backup.description,
             "--container",
-            self.new_backup.container,
+            self.backup.container,
             "--force",
             "--incremental",
             "--snapshot",
-            self.new_backup.snapshot_id,
-            self.new_backup.volume_id,
+            self.backup.snapshot_id,
+            self.backup.volume_id,
         ]
         verifylist = [
-            ("name", self.new_backup.name),
-            ("description", self.new_backup.description),
-            ("container", self.new_backup.container),
+            ("name", self.backup.name),
+            ("description", self.backup.description),
+            ("container", self.backup.container),
             ("force", True),
             ("incremental", True),
-            ("snapshot", self.new_backup.snapshot_id),
-            ("volume", self.new_backup.volume_id),
+            ("snapshot", self.backup.snapshot_id),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
         self.volume_sdk_client.create_backup.assert_called_with(
-            volume_id=self.new_backup.volume_id,
-            container=self.new_backup.container,
-            name=self.new_backup.name,
-            description=self.new_backup.description,
+            volume_id=self.backup.volume_id,
+            container=self.backup.container,
+            name=self.backup.name,
+            description=self.backup.description,
             force=True,
             is_incremental=True,
-            snapshot_id=self.new_backup.snapshot_id,
+            snapshot_id=self.backup.snapshot_id,
         )
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
@@ -108,18 +100,18 @@ class TestBackupCreate(volume_fakes.Test
             "foo=bar",
             "--property",
             "wow=much-cool",
-            self.new_backup.volume_id,
+            self.backup.volume_id,
         ]
         verifylist = [
             ("properties", {"foo": "bar", "wow": "much-cool"}),
-            ("volume", self.new_backup.volume_id),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
         self.volume_sdk_client.create_backup.assert_called_with(
-            volume_id=self.new_backup.volume_id,
+            volume_id=self.backup.volume_id,
             container=None,
             name=None,
             description=None,
@@ -138,11 +130,11 @@ class TestBackupCreate(volume_fakes.Test
             "foo=bar",
             "--property",
             "wow=much-cool",
-            self.new_backup.volume_id,
+            self.backup.volume_id,
         ]
         verifylist = [
             ("properties", {"foo": "bar", "wow": "much-cool"}),
-            ("volume", self.new_backup.volume_id),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -157,18 +149,18 @@ class TestBackupCreate(volume_fakes.Test
         arglist = [
             "--availability-zone",
             "my-az",
-            self.new_backup.volume_id,
+            self.backup.volume_id,
         ]
         verifylist = [
             ("availability_zone", "my-az"),
-            ("volume", self.new_backup.volume_id),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
         self.volume_sdk_client.create_backup.assert_called_with(
-            volume_id=self.new_backup.volume_id,
+            volume_id=self.backup.volume_id,
             container=None,
             name=None,
             description=None,
@@ -185,11 +177,11 @@ class TestBackupCreate(volume_fakes.Test
         arglist = [
             "--availability-zone",
             "my-az",
-            self.new_backup.volume_id,
+            self.backup.volume_id,
         ]
         verifylist = [
             ("availability_zone", "my-az"),
-            ("volume", self.new_backup.volume_id),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -201,25 +193,25 @@ class TestBackupCreate(volume_fakes.Test
     def test_backup_create_without_name(self):
         arglist = [
             "--description",
-            self.new_backup.description,
+            self.backup.description,
             "--container",
-            self.new_backup.container,
-            self.new_backup.volume_id,
+            self.backup.container,
+            self.backup.volume_id,
         ]
         verifylist = [
-            ("description", self.new_backup.description),
-            ("container", self.new_backup.container),
-            ("volume", self.new_backup.volume_id),
+            ("description", self.backup.description),
+            ("container", self.backup.container),
+            ("volume", self.backup.volume_id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
 
         self.volume_sdk_client.create_backup.assert_called_with(
-            volume_id=self.new_backup.volume_id,
-            container=self.new_backup.container,
+            volume_id=self.backup.volume_id,
+            container=self.backup.container,
             name=None,
-            description=self.new_backup.description,
+            description=self.backup.description,
             force=False,
             is_incremental=False,
         )
@@ -228,17 +220,13 @@ class TestBackupCreate(volume_fakes.Test
 
 
 class TestBackupDelete(volume_fakes.TestVolume):
-    backups = volume_fakes.create_backups(count=2)
-
     def setUp(self):
         super().setUp()
 
-        self.volume_sdk_client.find_backup = volume_fakes.get_backups(
-            self.backups
-        )
+        self.backups = list(sdk_fakes.generate_fake_resources(_backup.Backup))
+        self.volume_sdk_client.find_backup.side_effect = self.backups
         self.volume_sdk_client.delete_backup.return_value = None
 
-        # Get the command object to mock
         self.cmd = volume_backup.DeleteVolumeBackup(self.app, None)
 
     def test_backup_delete(self):
@@ -281,7 +269,7 @@ class TestBackupDelete(volume_fakes.Test
 
         calls = []
         for b in self.backups:
-            calls.append(call(b.id, ignore_missing=False, force=False))
+            calls.append(mock.call(b.id, ignore_missing=False, force=False))
         self.volume_sdk_client.delete_backup.assert_has_calls(calls)
         self.assertIsNone(result)
 
@@ -321,11 +309,6 @@ class TestBackupDelete(volume_fakes.Test
 
 
 class TestBackupList(volume_fakes.TestVolume):
-    volume = volume_fakes.create_one_volume()
-    backups = volume_fakes.create_backups(
-        attrs={'volume_id': volume.name}, count=3
-    )
-
     columns = (
         'ID',
         'Name',
@@ -341,45 +324,51 @@ class TestBackupList(volume_fakes.TestVo
         'Container',
     )
 
-    data = []
-    for b in backups:
-        data.append(
-            (
-                b.id,
-                b.name,
-                b.description,
-                b.status,
-                b.size,
-                b.is_incremental,
-                b.created_at,
-            )
-        )
-    data_long = []
-    for b in backups:
-        data_long.append(
-            (
-                b.id,
-                b.name,
-                b.description,
-                b.status,
-                b.size,
-                b.is_incremental,
-                b.created_at,
-                b.availability_zone,
-                volume_backup.VolumeIdColumn(b.volume_id),
-                b.container,
-            )
-        )
-
     def setUp(self):
         super().setUp()
 
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = self.volume
         self.volume_sdk_client.volumes.return_value = [self.volume]
+        self.backups = list(
+            sdk_fakes.generate_fake_resources(
+                _backup.Backup,
+                attrs={'volume_id': self.volume.id},
+            )
+        )
         self.volume_sdk_client.backups.return_value = self.backups
-        self.volume_sdk_client.find_volume.return_value = self.volume
         self.volume_sdk_client.find_backup.return_value = self.backups[0]
 
-        # Get the command to test
+        self.data = []
+        for b in self.backups:
+            self.data.append(
+                (
+                    b.id,
+                    b.name,
+                    b.description,
+                    b.status,
+                    b.size,
+                    b.is_incremental,
+                    b.created_at,
+                )
+            )
+        self.data_long = []
+        for b in self.backups:
+            self.data_long.append(
+                (
+                    b.id,
+                    b.name,
+                    b.description,
+                    b.status,
+                    b.size,
+                    b.is_incremental,
+                    b.created_at,
+                    b.availability_zone,
+                    volume_backup.VolumeIdColumn(b.volume_id),
+                    b.container,
+                )
+            )
+
         self.cmd = volume_backup.ListVolumeBackup(self.app, None)
 
     def test_backup_list_without_options(self):
@@ -457,35 +446,34 @@ class TestBackupList(volume_fakes.TestVo
 
 
 class TestBackupRestore(volume_fakes.TestVolume):
-    volume = volume_fakes.create_one_volume()
-    backup = volume_fakes.create_one_backup(
-        attrs={'volume_id': volume.id},
-    )
-
     columns = (
         "id",
         "volume_id",
         "volume_name",
     )
 
-    data = (
-        backup.id,
-        volume.id,
-        volume.name,
-    )
-
     def setUp(self):
         super().setUp()
 
-        self.volume_sdk_client.find_backup.return_value = self.backup
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
         self.volume_sdk_client.find_volume.return_value = self.volume
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup, volume_id=self.volume.id
+        )
+        self.volume_sdk_client.find_backup.return_value = self.backup
+        self.volume_sdk_client.create_backup.return_value = self.backup
         self.volume_sdk_client.restore_backup.return_value = {
             'id': self.backup['id'],
             'volume_id': self.volume['id'],
             'volume_name': self.volume['name'],
         }
 
-        # Get the command object to mock
+        self.data = (
+            self.backup.id,
+            self.volume.id,
+            self.volume.name,
+        )
+
         self.cmd = volume_backup.RestoreVolumeBackup(self.app, None)
 
     def test_backup_restore(self):
@@ -574,17 +562,15 @@ class TestBackupRestore(volume_fakes.Tes
         )
 
 
-class TestBackupSet(TestBackupLegacy):
-    backup = volume_fakes.create_one_backup(
-        attrs={'metadata': {'wow': 'cool'}},
-    )
-
+class TestBackupSet(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.backups_mock.get.return_value = self.backup
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup, metadata={'wow': 'cool'}
+        )
+        self.volume_sdk_client.find_backup.return_value = self.backup
 
-        # Get the command object to test
         self.cmd = volume_backup.SetVolumeBackup(self.app, None)
 
     def test_backup_set_name(self):
@@ -601,14 +587,16 @@ class TestBackupSet(TestBackupLegacy):
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        # In base command class ShowOne in cliff, abstract method take_action()
-        # returns nothing
         result = self.cmd.take_action(parsed_args)
-        self.backups_mock.update.assert_called_once_with(
-            self.backup.id, **{'name': 'new_name'}
-        )
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.update_backup.assert_called_once_with(
+            self.backup, name='new_name'
+        )
+
     def test_backup_set_name_pre_v39(self):
         self.set_volume_api_version('3.8')
 
@@ -644,13 +632,14 @@ class TestBackupSet(TestBackupLegacy):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        # Set expected values
-        kwargs = {'description': 'new_description'}
-        self.backups_mock.update.assert_called_once_with(
-            self.backup.id, **kwargs
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.update_backup.assert_called_once_with(
+            self.backup, description='new_description'
         )
-        self.assertIsNone(result)
 
     def test_backup_set_description_pre_v39(self):
         self.set_volume_api_version('3.8')
@@ -679,26 +668,34 @@ class TestBackupSet(TestBackupLegacy):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
-        self.backups_mock.reset_state.assert_called_once_with(
-            self.backup.id, 'error'
-        )
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_backup_status.assert_called_with(
+            self.backup, status='error'
+        )
+
     def test_backup_set_state_failed(self):
-        self.backups_mock.reset_state.side_effect = exceptions.CommandError()
+        self.volume_sdk_client.reset_backup_status.side_effect = (
+            sdk_exceptions.NotFoundException('foo')
+        )
+
         arglist = ['--state', 'error', self.backup.id]
         verifylist = [('state', 'error'), ('backup', self.backup.id)]
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        try:
-            self.cmd.take_action(parsed_args)
-            self.fail('CommandError should be raised.')
-        except exceptions.CommandError as e:
-            self.assertEqual(
-                'One or more of the set operations failed', str(e)
-            )
-        self.backups_mock.reset_state.assert_called_with(
-            self.backup.id, 'error'
+        exc = self.assertRaises(
+            exceptions.CommandError, self.cmd.take_action, parsed_args
+        )
+        self.assertEqual('One or more of the set operations failed', str(exc))
+
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_backup_status.assert_called_with(
+            self.backup, status='error'
         )
 
     def test_backup_set_no_property(self):
@@ -715,15 +712,14 @@ class TestBackupSet(TestBackupLegacy):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        # Set expected values
-        kwargs = {
-            'metadata': {},
-        }
-        self.backups_mock.update.assert_called_once_with(
-            self.backup.id, **kwargs
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.update_backup.assert_called_once_with(
+            self.backup, metadata={}
         )
-        self.assertIsNone(result)
 
     def test_backup_set_no_property_pre_v343(self):
         self.set_volume_api_version('3.42')
@@ -758,15 +754,14 @@ class TestBackupSet(TestBackupLegacy):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        # Set expected values
-        kwargs = {
-            'metadata': {'wow': 'cool', 'foo': 'bar'},
-        }
-        self.backups_mock.update.assert_called_once_with(
-            self.backup.id, **kwargs
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.update_backup.assert_called_once_with(
+            self.backup, metadata={'wow': 'cool', 'foo': 'bar'}
         )
-        self.assertIsNone(result)
 
     def test_backup_set_property_pre_v343(self):
         self.set_volume_api_version('3.42')
@@ -788,17 +783,16 @@ class TestBackupSet(TestBackupLegacy):
         self.assertIn("--os-volume-api-version 3.43 or greater", str(exc))
 
 
-class TestBackupUnset(TestBackupLegacy):
-    backup = volume_fakes.create_one_backup(
-        attrs={'metadata': {'foo': 'bar'}},
-    )
-
+class TestBackupUnset(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.backups_mock.get.return_value = self.backup
+        self.backup = sdk_fakes.generate_fake_resource(
+            _backup.Backup, metadata={'foo': 'bar', 'wow': 'cool'}
+        )
+        self.volume_sdk_client.find_backup.return_value = self.backup
+        self.volume_sdk_client.delete_backup_metadata.return_value = None
 
-        # Get the command object to test
         self.cmd = volume_backup.UnsetVolumeBackup(self.app, None)
 
     def test_backup_unset_property(self):
@@ -816,15 +810,14 @@ class TestBackupUnset(TestBackupLegacy):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        # Set expected values
-        kwargs = {
-            'metadata': {},
-        }
-        self.backups_mock.update.assert_called_once_with(
-            self.backup.id, **kwargs
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_backup_metadata.assert_called_once_with(
+            self.backup, keys=['wow']
         )
-        self.assertIsNone(result)
 
     def test_backup_unset_property_pre_v343(self):
         self.set_volume_api_version('3.42')
@@ -847,8 +840,6 @@ class TestBackupUnset(TestBackupLegacy):
 
 
 class TestBackupShow(volume_fakes.TestVolume):
-    backup = volume_fakes.create_one_backup()
-
     columns = (
         "availability_zone",
         "container",
@@ -871,34 +862,36 @@ class TestBackupShow(volume_fakes.TestVo
         "user_id",
         "volume_id",
     )
-    data = (
-        backup.availability_zone,
-        backup.container,
-        backup.created_at,
-        backup.data_timestamp,
-        backup.description,
-        backup.encryption_key_id,
-        backup.fail_reason,
-        backup.has_dependent_backups,
-        backup.id,
-        backup.is_incremental,
-        backup.metadata,
-        backup.name,
-        backup.object_count,
-        backup.project_id,
-        backup.size,
-        backup.snapshot_id,
-        backup.status,
-        backup.updated_at,
-        backup.user_id,
-        backup.volume_id,
-    )
 
     def setUp(self):
         super().setUp()
 
+        self.backup = sdk_fakes.generate_fake_resource(_backup.Backup)
         self.volume_sdk_client.find_backup.return_value = self.backup
-        # Get the command object to test
+
+        self.data = (
+            self.backup.availability_zone,
+            self.backup.container,
+            self.backup.created_at,
+            self.backup.data_timestamp,
+            self.backup.description,
+            self.backup.encryption_key_id,
+            self.backup.fail_reason,
+            self.backup.has_dependent_backups,
+            self.backup.id,
+            self.backup.is_incremental,
+            self.backup.metadata,
+            self.backup.name,
+            self.backup.object_count,
+            self.backup.project_id,
+            self.backup.size,
+            self.backup.snapshot_id,
+            self.backup.status,
+            self.backup.updated_at,
+            self.backup.user_id,
+            self.backup.volume_id,
+        )
+
         self.cmd = volume_backup.ShowVolumeBackup(self.app, None)
 
     def test_backup_show(self):
@@ -907,7 +900,9 @@ class TestBackupShow(volume_fakes.TestVo
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.volume_sdk_client.find_backup.assert_called_with(self.backup.id)
+        self.volume_sdk_client.find_backup.assert_called_with(
+            self.backup.id, ignore_missing=False
+        )
 
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, data)
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_snapshot.py	2025-07-07 22:41:56.000000000 +0000
@@ -13,34 +13,185 @@
 
 from unittest import mock
 
+from openstack.block_storage.v3 import snapshot as _snapshot
+from openstack.block_storage.v3 import volume as _volume
+from openstack import exceptions as sdk_exceptions
+from openstack.test import fakes as sdk_fakes
+from osc_lib.cli import format_columns
 from osc_lib import exceptions
-from osc_lib import utils
 
-from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
-from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes_v3
+from openstackclient.tests.unit.identity.v3 import fakes as project_fakes
+from openstackclient.tests.unit import utils as test_utils
+from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
 from openstackclient.volume.v3 import volume_snapshot
 
 
-class TestVolumeSnapshot(volume_fakes_v3.TestVolume):
+class TestVolumeSnapshotCreate(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.snapshots_mock = self.volume_client.volume_snapshots
-        self.snapshots_mock.reset_mock()
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.volume_sdk_client.find_volume.return_value = self.volume
+        self.snapshot = sdk_fakes.generate_fake_resource(
+            _snapshot.Snapshot, volume_id=self.volume.id
+        )
+        self.volume_sdk_client.create_snapshot.return_value = self.snapshot
+        self.volume_sdk_client.manage_snapshot.return_value = self.snapshot
 
-        self.volume_sdk_client.unmanage_snapshot.return_value = None
+        self.columns = (
+            'created_at',
+            'description',
+            'id',
+            'name',
+            'properties',
+            'size',
+            'status',
+            'volume_id',
+        )
+        self.data = (
+            self.snapshot.created_at,
+            self.snapshot.description,
+            self.snapshot.id,
+            self.snapshot.name,
+            format_columns.DictColumn(self.snapshot.metadata),
+            self.snapshot.size,
+            self.snapshot.status,
+            self.snapshot.volume_id,
+        )
+
+        self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None)
+
+    def test_snapshot_create(self):
+        arglist = [
+            "--volume",
+            self.snapshot.volume_id,
+            "--description",
+            self.snapshot.description,
+            "--force",
+            '--property',
+            'Alpha=a',
+            '--property',
+            'Beta=b',
+            self.snapshot.name,
+        ]
+        verifylist = [
+            ("volume", self.snapshot.volume_id),
+            ("description", self.snapshot.description),
+            ("force", True),
+            ('properties', {'Alpha': 'a', 'Beta': 'b'}),
+            ("snapshot_name", self.snapshot.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.snapshot.volume_id, ignore_missing=False
+        )
+        self.volume_sdk_client.create_snapshot.assert_called_with(
+            volume_id=self.snapshot.volume_id,
+            force=True,
+            name=self.snapshot.name,
+            description=self.snapshot.description,
+            metadata={'Alpha': 'a', 'Beta': 'b'},
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+
+    def test_snapshot_create_without_name(self):
+        arglist = [
+            "--volume",
+            self.snapshot.volume_id,
+        ]
+        verifylist = [
+            ("volume", self.snapshot.volume_id),
+        ]
+        self.assertRaises(
+            test_utils.ParserException,
+            self.check_parser,
+            self.cmd,
+            arglist,
+            verifylist,
+        )
+
+    def test_snapshot_create_without_volume(self):
+        arglist = [
+            "--description",
+            self.snapshot.description,
+            "--force",
+            self.snapshot.name,
+        ]
+        verifylist = [
+            ("description", self.snapshot.description),
+            ("force", True),
+            ("snapshot_name", self.snapshot.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.snapshot.name, ignore_missing=False
+        )
+        self.volume_sdk_client.create_snapshot.assert_called_with(
+            volume_id=self.snapshot.volume_id,
+            force=True,
+            name=self.snapshot.name,
+            description=self.snapshot.description,
+            metadata=None,
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+
+    def test_snapshot_create_with_remote_source(self):
+        arglist = [
+            '--remote-source',
+            'source-name=test_source_name',
+            '--remote-source',
+            'source-id=test_source_id',
+            '--volume',
+            self.snapshot.volume_id,
+            self.snapshot.name,
+        ]
+        ref_dict = {
+            'source-name': 'test_source_name',
+            'source-id': 'test_source_id',
+        }
+        verifylist = [
+            ('remote_source', ref_dict),
+            ('volume', self.snapshot.volume_id),
+            ("snapshot_name", self.snapshot.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
 
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+        self.volume_sdk_client.find_volume.assert_called_once_with(
+            self.snapshot.volume_id, ignore_missing=False
+        )
+        self.volume_sdk_client.manage_snapshot.assert_called_with(
+            volume_id=self.snapshot.volume_id,
+            ref=ref_dict,
+            name=self.snapshot.name,
+            description=None,
+            metadata=None,
+        )
+        self.volume_sdk_client.create_snapshot.assert_not_called()
 
-class TestVolumeSnapshotDelete(TestVolumeSnapshot):
-    snapshots = volume_fakes.create_snapshots(count=2)
 
+class TestVolumeSnapshotDelete(volume_fakes.TestVolume):
     def setUp(self):
         super().setUp()
 
-        self.snapshots_mock.get = volume_fakes.get_snapshots(self.snapshots)
-        self.snapshots_mock.delete.return_value = None
+        self.snapshots = list(
+            sdk_fakes.generate_fake_resources(_snapshot.Snapshot)
+        )
+        self.volume_sdk_client.find_snapshot.side_effect = self.snapshots
+        self.volume_sdk_client.delete_snapshot.return_value = None
+        self.volume_sdk_client.unmanage_snapshot.return_value = None
 
-        # Get the command object to mock
         self.cmd = volume_snapshot.DeleteVolumeSnapshot(self.app, None)
 
     def test_snapshot_delete(self):
@@ -49,11 +200,14 @@ class TestVolumeSnapshotDelete(TestVolum
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.snapshots_mock.delete.assert_called_with(
-            self.snapshots[0].id, False
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            self.snapshots[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_snapshot.assert_called_once_with(
+            self.snapshots[0].id, force=False
         )
-        self.assertIsNone(result)
 
     def test_snapshot_delete_with_force(self):
         arglist = ['--force', self.snapshots[0].id]
@@ -61,11 +215,14 @@ class TestVolumeSnapshotDelete(TestVolum
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
-        self.snapshots_mock.delete.assert_called_with(
-            self.snapshots[0].id, True
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            self.snapshots[0].id, ignore_missing=False
+        )
+        self.volume_sdk_client.delete_snapshot.assert_called_once_with(
+            self.snapshots[0].id, force=True
         )
-        self.assertIsNone(result)
 
     def test_delete_multiple_snapshots(self):
         arglist = []
@@ -74,17 +231,24 @@ class TestVolumeSnapshotDelete(TestVolum
         verifylist = [
             ('snapshots', arglist),
         ]
-
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        result = self.cmd.take_action(parsed_args)
 
-        calls = []
-        for s in self.snapshots:
-            calls.append(mock.call(s.id, False))
-        self.snapshots_mock.delete.assert_has_calls(calls)
+        result = self.cmd.take_action(parsed_args)
         self.assertIsNone(result)
 
+        self.volume_sdk_client.find_snapshot.assert_has_calls(
+            [mock.call(x.id, ignore_missing=False) for x in self.snapshots]
+        )
+        self.volume_sdk_client.delete_snapshot.assert_has_calls(
+            [mock.call(x.id, force=False) for x in self.snapshots]
+        )
+
     def test_delete_multiple_snapshots_with_exception(self):
+        self.volume_sdk_client.find_snapshot.side_effect = [
+            self.snapshots[0],
+            sdk_exceptions.NotFoundException(),
+        ]
+
         arglist = [
             self.snapshots[0].id,
             'unexist_snapshot',
@@ -95,25 +259,24 @@ class TestVolumeSnapshotDelete(TestVolum
 
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        find_mock_result = [self.snapshots[0], exceptions.CommandError]
-        with mock.patch.object(
-            utils, 'find_resource', side_effect=find_mock_result
-        ) as find_mock:
-            try:
-                self.cmd.take_action(parsed_args)
-                self.fail('CommandError should be raised.')
-            except exceptions.CommandError as e:
-                self.assertEqual('1 of 2 snapshots failed to delete.', str(e))
-
-            find_mock.assert_any_call(
-                self.snapshots_mock, self.snapshots[0].id
-            )
-            find_mock.assert_any_call(self.snapshots_mock, 'unexist_snapshot')
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+        self.assertEqual('1 of 2 snapshots failed to delete.', str(exc))
 
-            self.assertEqual(2, find_mock.call_count)
-            self.snapshots_mock.delete.assert_called_once_with(
-                self.snapshots[0].id, False
-            )
+        self.volume_sdk_client.find_snapshot.assert_has_calls(
+            [
+                mock.call(self.snapshots[0].id, ignore_missing=False),
+                mock.call('unexist_snapshot', ignore_missing=False),
+            ]
+        )
+        self.volume_sdk_client.delete_snapshot.assert_has_calls(
+            [
+                mock.call(self.snapshots[0].id, force=False),
+            ]
+        )
 
     def test_snapshot_delete_remote(self):
         arglist = ['--remote', self.snapshots[0].id]
@@ -121,11 +284,11 @@ class TestVolumeSnapshotDelete(TestVolum
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
 
         self.volume_sdk_client.unmanage_snapshot.assert_called_with(
             self.snapshots[0].id
         )
-        self.assertIsNone(result)
 
     def test_snapshot_delete_with_remote_force(self):
         arglist = ['--remote', '--force', self.snapshots[0].id]
@@ -140,8 +303,7 @@ class TestVolumeSnapshotDelete(TestVolum
             exceptions.CommandError, self.cmd.take_action, parsed_args
         )
         self.assertIn(
-            "The --force option is not supported with the --remote "
-            "parameter.",
+            "The --force option is not supported with the --remote parameter.",
             str(exc),
         )
 
@@ -150,12 +312,484 @@ class TestVolumeSnapshotDelete(TestVolum
         for s in self.snapshots:
             arglist.append(s.id)
         verifylist = [('remote', True), ('snapshots', arglist[1:])]
-
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
         result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
+
+        self.volume_sdk_client.unmanage_snapshot.assert_has_calls(
+            [mock.call(s.id) for s in self.snapshots]
+        )
+
+
+class TestVolumeSnapshotList(volume_fakes.TestVolume):
+    def setUp(self):
+        super().setUp()
+
+        self.volume = sdk_fakes.generate_fake_resource(_volume.Volume)
+        self.snapshots = list(
+            sdk_fakes.generate_fake_resources(
+                _snapshot.Snapshot, attrs={'volume_id': self.volume.name}
+            )
+        )
+        self.project = project_fakes.FakeProject.create_one_project()
+        self.volume_sdk_client.volumes.return_value = [self.volume]
+        self.volume_sdk_client.find_volume.return_value = self.volume
+        self.volume_sdk_client.snapshots.return_value = self.snapshots
+        self.project_mock = self.identity_client.projects
+        self.project_mock.get.return_value = self.project
+
+        self.columns = ("ID", "Name", "Description", "Status", "Size")
+        self.columns_long = self.columns + (
+            "Created At",
+            "Volume",
+            "Properties",
+        )
 
-        calls = []
+        self.data = []
+        self.data_long = []
         for s in self.snapshots:
-            calls.append(mock.call(s.id))
-        self.volume_sdk_client.unmanage_snapshot.assert_has_calls(calls)
+            self.data.append(
+                (
+                    s.id,
+                    s.name,
+                    s.description,
+                    s.status,
+                    s.size,
+                )
+            )
+            self.data_long.append(
+                (
+                    s.id,
+                    s.name,
+                    s.description,
+                    s.status,
+                    s.size,
+                    s.created_at,
+                    volume_snapshot.VolumeIdColumn(
+                        s.volume_id, volume_cache={self.volume.id: self.volume}
+                    ),
+                    format_columns.DictColumn(s.metadata),
+                )
+            )
+
+        self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
+
+    def test_snapshot_list_without_options(self):
+        arglist = []
+        verifylist = [('all_projects', False), ('long', False)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.snapshots.assert_called_once_with(
+            limit=None,
+            marker=None,
+            all_projects=False,
+            name=None,
+            status=None,
+            project_id=None,
+            volume_id=None,
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
+    def test_snapshot_list_with_options(self):
+        arglist = [
+            "--long",
+            "--limit",
+            "2",
+            "--project",
+            self.project.id,
+            "--marker",
+            self.snapshots[0].id,
+        ]
+        verifylist = [
+            ("long", True),
+            ("limit", 2),
+            ("project", self.project.id),
+            ("marker", self.snapshots[0].id),
+            ('all_projects', False),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.snapshots.assert_called_once_with(
+            limit=2,
+            marker=self.snapshots[0].id,
+            all_projects=True,
+            project_id=self.project.id,
+            name=None,
+            status=None,
+            volume_id=None,
+        )
+        self.assertEqual(self.columns_long, columns)
+        self.assertEqual(self.data_long, list(data))
+
+    def test_snapshot_list_all_projects(self):
+        arglist = [
+            '--all-projects',
+        ]
+        verifylist = [('long', False), ('all_projects', True)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.snapshots.assert_called_once_with(
+            limit=None,
+            marker=None,
+            all_projects=True,
+            name=None,
+            status=None,
+            project_id=None,
+            volume_id=None,
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
+    def test_snapshot_list_name_option(self):
+        arglist = [
+            '--name',
+            self.snapshots[0].name,
+        ]
+        verifylist = [
+            ('all_projects', False),
+            ('long', False),
+            ('name', self.snapshots[0].name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.snapshots.assert_called_once_with(
+            limit=None,
+            marker=None,
+            all_projects=False,
+            name=self.snapshots[0].name,
+            status=None,
+            project_id=None,
+            volume_id=None,
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
+    def test_snapshot_list_status_option(self):
+        arglist = [
+            '--status',
+            'available',
+        ]
+        verifylist = [
+            ('all_projects', False),
+            ('long', False),
+            ('status', 'available'),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.snapshots.assert_called_once_with(
+            limit=None,
+            marker=None,
+            all_projects=False,
+            name=None,
+            status='available',
+            project_id=None,
+            volume_id=None,
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
+    def test_snapshot_list_volumeid_option(self):
+        arglist = [
+            '--volume',
+            self.volume.id,
+        ]
+        verifylist = [
+            ('all_projects', False),
+            ('long', False),
+            ('volume', self.volume.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.volume_sdk_client.snapshots.assert_called_once_with(
+            limit=None,
+            marker=None,
+            all_projects=False,
+            name=None,
+            status=None,
+            project_id=None,
+            volume_id=self.volume.id,
+        )
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
+    def test_snapshot_list_negative_limit(self):
+        arglist = [
+            "--limit",
+            "-2",
+        ]
+        verifylist = [
+            ("limit", -2),
+        ]
+        self.assertRaises(
+            test_utils.ParserException,
+            self.check_parser,
+            self.cmd,
+            arglist,
+            verifylist,
+        )
+
+
+class TestVolumeSnapshotSet(volume_fakes.TestVolume):
+    def setUp(self):
+        super().setUp()
+
+        self.snapshot = sdk_fakes.generate_fake_resource(
+            _snapshot.Snapshot, metadata={'foo': 'bar'}
+        )
+        self.volume_sdk_client.find_snapshot.return_value = self.snapshot
+        self.volume_sdk_client.set_snapshot_metadata.return_value = None
+        self.volume_sdk_client.update_snapshot.return_value = None
+        # Get the command object to mock
+        self.cmd = volume_snapshot.SetVolumeSnapshot(self.app, None)
+
+    def test_snapshot_set_no_option(self):
+        arglist = [
+            self.snapshot.id,
+        ]
+        verifylist = [
+            ("snapshot", self.snapshot.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            parsed_args.snapshot, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_snapshot_status.assert_not_called()
+        self.volume_sdk_client.update_snapshot.assert_not_called()
+        self.volume_sdk_client.set_snapshot_metadata.assert_not_called()
+
+    def test_snapshot_set_name_and_property(self):
+        arglist = [
+            "--name",
+            "new_snapshot",
+            "--property",
+            "x=y",
+            "--property",
+            "foo=foo",
+            self.snapshot.id,
+        ]
+        verifylist = [
+            ("name", "new_snapshot"),
+            ("properties", {"x": "y", "foo": "foo"}),
+            ("snapshot", self.snapshot.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+        self.volume_sdk_client.update_snapshot.assert_called_with(
+            self.snapshot.id, name="new_snapshot"
+        )
+        self.volume_sdk_client.set_snapshot_metadata.assert_called_with(
+            self.snapshot.id, x="y", foo="foo"
+        )
+
+    def test_snapshot_set_with_no_property(self):
+        arglist = [
+            "--no-property",
+            self.snapshot.id,
+        ]
+        verifylist = [
+            ("no_property", True),
+            ("snapshot", self.snapshot.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            parsed_args.snapshot, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_snapshot_status.assert_not_called()
+        self.volume_sdk_client.update_snapshot.assert_not_called()
+        self.volume_sdk_client.set_snapshot_metadata.assert_not_called()
+        self.volume_sdk_client.delete_snapshot_metadata.assert_called_with(
+            self.snapshot.id, keys=["foo"]
+        )
+
+    def test_snapshot_set_with_no_property_and_property(self):
+        arglist = [
+            "--no-property",
+            "--property",
+            "foo_1=bar_1",
+            self.snapshot.id,
+        ]
+        verifylist = [
+            ("no_property", True),
+            ("properties", {"foo_1": "bar_1"}),
+            ("snapshot", self.snapshot.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
         self.assertIsNone(result)
+        self.volume_sdk_client.find_snapshot.assert_called_once_with(
+            parsed_args.snapshot, ignore_missing=False
+        )
+        self.volume_sdk_client.reset_snapshot_status.assert_not_called()
+        self.volume_sdk_client.update_snapshot.assert_not_called()
+        self.volume_sdk_client.delete_snapshot_metadata.assert_called_with(
+            self.snapshot.id, keys=["foo"]
+        )
+        self.volume_sdk_client.set_snapshot_metadata.assert_called_once_with(
+            self.snapshot.id,
+            foo_1="bar_1",
+        )
+
+    def test_snapshot_set_state_to_error(self):
+        arglist = ["--state", "error", self.snapshot.id]
+        verifylist = [("state", "error"), ("snapshot", self.snapshot.id)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+        self.volume_sdk_client.reset_snapshot_status.assert_called_with(
+            self.snapshot.id, "error"
+        )
+
+    def test_volume_set_state_failed(self):
+        self.volume_sdk_client.reset_snapshot_status.side_effect = (
+            exceptions.CommandError()
+        )
+        arglist = ['--state', 'error', self.snapshot.id]
+        verifylist = [('state', 'error'), ('snapshot', self.snapshot.id)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+
+        self.assertEqual('One or more of the set operations failed', str(exc))
+        self.volume_sdk_client.reset_snapshot_status.assert_called_once_with(
+            self.snapshot.id, 'error'
+        )
+
+    def test_volume_set_name_and_state_failed(self):
+        self.volume_sdk_client.reset_snapshot_status.side_effect = (
+            exceptions.CommandError()
+        )
+        arglist = [
+            '--state',
+            'error',
+            "--name",
+            "new_snapshot",
+            self.snapshot.id,
+        ]
+        verifylist = [
+            ('state', 'error'),
+            ("name", "new_snapshot"),
+            ('snapshot', self.snapshot.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        exc = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
+        )
+
+        self.assertEqual('One or more of the set operations failed', str(exc))
+        self.volume_sdk_client.update_snapshot.assert_called_once_with(
+            self.snapshot.id, name="new_snapshot"
+        )
+        self.volume_sdk_client.reset_snapshot_status.assert_called_once_with(
+            self.snapshot.id, 'error'
+        )
+
+
+class TestVolumeSnapshotShow(volume_fakes.TestVolume):
+    def setUp(self):
+        super().setUp()
+
+        self.snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
+
+        self.columns = (
+            'created_at',
+            'description',
+            'id',
+            'name',
+            'properties',
+            'size',
+            'status',
+            'volume_id',
+        )
+        self.data = (
+            self.snapshot.created_at,
+            self.snapshot.description,
+            self.snapshot.id,
+            self.snapshot.name,
+            format_columns.DictColumn(self.snapshot.metadata),
+            self.snapshot.size,
+            self.snapshot.status,
+            self.snapshot.volume_id,
+        )
+
+        self.volume_sdk_client.find_snapshot.return_value = self.snapshot
+
+        self.cmd = volume_snapshot.ShowVolumeSnapshot(self.app, None)
+
+    def test_snapshot_show(self):
+        arglist = [self.snapshot.id]
+        verifylist = [("snapshot", self.snapshot.id)]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        self.volume_sdk_client.find_snapshot.assert_called_with(
+            self.snapshot.id, ignore_missing=False
+        )
+
+        self.assertEqual(self.columns, columns)
+        self.assertCountEqual(self.data, data)
+
+
+class TestVolumeSnapshotUnset(volume_fakes.TestVolume):
+    def setUp(self):
+        super().setUp()
+
+        self.snapshot = sdk_fakes.generate_fake_resource(_snapshot.Snapshot)
+        self.volume_sdk_client.find_snapshot.return_value = self.snapshot
+        self.volume_sdk_client.delete_snapshot_metadata.return_value = None
+
+        self.cmd = volume_snapshot.UnsetVolumeSnapshot(self.app, None)
+
+    def test_snapshot_unset(self):
+        arglist = [
+            "--property",
+            "foo",
+            self.snapshot.id,
+        ]
+        verifylist = [
+            ("properties", ["foo"]),
+            ("snapshot", self.snapshot.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+        self.volume_sdk_client.delete_snapshot_metadata.assert_called_with(
+            self.snapshot.id, keys=["foo"]
+        )
diff -pruN 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py
--- 7.4.0-3/openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py	2025-07-07 22:41:56.000000000 +0000
@@ -284,7 +284,7 @@ class TestTransferDelete(TestTransfer):
                 self.fail('CommandError should be raised.')
             except exceptions.CommandError as e:
                 self.assertEqual(
-                    '1 of 2 volume transfer requests failed ' 'to delete',
+                    '1 of 2 volume transfer requests failed to delete',
                     str(e),
                 )
 
diff -pruN 7.4.0-3/openstackclient/volume/client.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/client.py
--- 7.4.0-3/openstackclient/volume/client.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/client.py	2025-07-07 22:41:56.000000000 +0000
@@ -105,9 +105,7 @@ def build_option_parser(parser):
         '--os-volume-api-version',
         metavar='<volume-api-version>',
         default=utils.env('OS_VOLUME_API_VERSION'),
-        help=_(
-            'Volume API version, default=%s ' '(Env: OS_VOLUME_API_VERSION)'
-        )
+        help=_('Volume API version, default=%s (Env: OS_VOLUME_API_VERSION)')
         % DEFAULT_API_VERSION,
     )
     return parser
diff -pruN 7.4.0-3/openstackclient/volume/v1/qos_specs.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/qos_specs.py
--- 7.4.0-3/openstackclient/volume/v1/qos_specs.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/qos_specs.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,377 +0,0 @@
-#   Copyright 2015 iWeb Technologies Inc.
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Volume v1 QoS action implementations"""
-
-import logging
-
-from osc_lib.cli import format_columns
-from osc_lib.cli import parseractions
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AssociateQos(command.Command):
-    _description = _("Associate a QoS specification to a volume type")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'qos_spec',
-            metavar='<qos-spec>',
-            help=_('QoS specification to modify (name or ID)'),
-        )
-        parser.add_argument(
-            'volume_type',
-            metavar='<volume-type>',
-            help=_('Volume type to associate the QoS (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        qos_spec = utils.find_resource(
-            volume_client.qos_specs, parsed_args.qos_spec
-        )
-        volume_type = utils.find_resource(
-            volume_client.volume_types, parsed_args.volume_type
-        )
-
-        volume_client.qos_specs.associate(qos_spec.id, volume_type.id)
-
-
-class CreateQos(command.ShowOne):
-    _description = _("Create new QoS specification")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'name',
-            metavar='<name>',
-            help=_('New QoS specification name'),
-        )
-        consumer_choices = ['front-end', 'back-end', 'both']
-        parser.add_argument(
-            '--consumer',
-            metavar='<consumer>',
-            choices=consumer_choices,
-            default='both',
-            help=(
-                _(
-                    'Consumer of the QoS. Valid consumers: %s '
-                    "(defaults to 'both')"
-                )
-                % utils.format_list(consumer_choices)
-            ),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Set a QoS specification property '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        specs = {}
-        specs.update({'consumer': parsed_args.consumer})
-
-        if parsed_args.property:
-            specs.update(parsed_args.property)
-
-        qos_spec = volume_client.qos_specs.create(parsed_args.name, specs)
-        qos_spec._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    qos_spec._info.pop('specs')
-                )
-            }
-        )
-        return zip(*sorted(qos_spec._info.items()))
-
-
-class DeleteQos(command.Command):
-    _description = _("Delete QoS specification")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'qos_specs',
-            metavar='<qos-spec>',
-            nargs="+",
-            help=_('QoS specification(s) to delete (name or ID)'),
-        )
-        parser.add_argument(
-            '--force',
-            action='store_true',
-            default=False,
-            help=_("Allow to delete in-use QoS specification(s)"),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        result = 0
-
-        for i in parsed_args.qos_specs:
-            try:
-                qos_spec = utils.find_resource(volume_client.qos_specs, i)
-                volume_client.qos_specs.delete(qos_spec.id, parsed_args.force)
-            except Exception as e:
-                result += 1
-                LOG.error(
-                    _(
-                        "Failed to delete QoS specification with "
-                        "name or ID '%(qos)s': %(e)s"
-                    ),
-                    {'qos': i, 'e': e},
-                )
-
-        if result > 0:
-            total = len(parsed_args.qos_specs)
-            msg = _(
-                "%(result)s of %(total)s QoS specifications failed"
-                " to delete."
-            ) % {'result': result, 'total': total}
-            raise exceptions.CommandError(msg)
-
-
-class DisassociateQos(command.Command):
-    _description = _("Disassociate a QoS specification from a volume type")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'qos_spec',
-            metavar='<qos-spec>',
-            help=_('QoS specification to modify (name or ID)'),
-        )
-        volume_type_group = parser.add_mutually_exclusive_group()
-        volume_type_group.add_argument(
-            '--volume-type',
-            metavar='<volume-type>',
-            help=_('Volume type to disassociate the QoS from (name or ID)'),
-        )
-        volume_type_group.add_argument(
-            '--all',
-            action='store_true',
-            default=False,
-            help=_('Disassociate the QoS from every volume type'),
-        )
-
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        qos_spec = utils.find_resource(
-            volume_client.qos_specs, parsed_args.qos_spec
-        )
-
-        if parsed_args.volume_type:
-            volume_type = utils.find_resource(
-                volume_client.volume_types, parsed_args.volume_type
-            )
-            volume_client.qos_specs.disassociate(qos_spec.id, volume_type.id)
-        elif parsed_args.all:
-            volume_client.qos_specs.disassociate_all(qos_spec.id)
-
-
-class ListQos(command.Lister):
-    _description = _("List QoS specifications")
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        qos_specs_list = volume_client.qos_specs.list()
-
-        for qos in qos_specs_list:
-            try:
-                qos_associations = volume_client.qos_specs.get_associations(
-                    qos,
-                )
-                if qos_associations:
-                    associations = [
-                        association.name for association in qos_associations
-                    ]
-                    qos._info.update({'associations': associations})
-            except Exception as ex:
-                if type(ex).__name__ == 'NotFound':
-                    qos._info.update({'associations': None})
-                else:
-                    raise
-
-        display_columns = (
-            'ID',
-            'Name',
-            'Consumer',
-            'Associations',
-            'Properties',
-        )
-        columns = ('ID', 'Name', 'Consumer', 'Associations', 'Specs')
-        return (
-            display_columns,
-            (
-                utils.get_dict_properties(
-                    s._info,
-                    columns,
-                    formatters={
-                        'Specs': format_columns.DictColumn,
-                        'Associations': format_columns.ListColumn,
-                    },
-                )
-                for s in qos_specs_list
-            ),
-        )
-
-
-class SetQos(command.Command):
-    _description = _("Set QoS specification properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'qos_spec',
-            metavar='<qos-spec>',
-            help=_('QoS specification to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--no-property',
-            dest='no_property',
-            action='store_true',
-            help=_(
-                'Remove all properties from <qos-spec> '
-                '(specify both --no-property and --property to remove the '
-                'current properties before setting new properties)'
-            ),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Property to add or modify for this QoS specification '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        qos_spec = utils.find_resource(
-            volume_client.qos_specs, parsed_args.qos_spec
-        )
-
-        result = 0
-        if parsed_args.no_property:
-            try:
-                key_list = list(qos_spec._info['specs'].keys())
-                volume_client.qos_specs.unset_keys(qos_spec.id, key_list)
-            except Exception as e:
-                LOG.error(_("Failed to clean qos properties: %s"), e)
-                result += 1
-
-        if parsed_args.property:
-            try:
-                volume_client.qos_specs.set_keys(
-                    qos_spec.id,
-                    parsed_args.property,
-                )
-            except Exception as e:
-                LOG.error(_("Failed to set qos property: %s"), e)
-                result += 1
-
-        if result > 0:
-            raise exceptions.CommandError(
-                _("One or more of the set operations failed")
-            )
-
-
-class ShowQos(command.ShowOne):
-    _description = _("Display QoS specification details")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'qos_spec',
-            metavar='<qos-spec>',
-            help=_('QoS specification to display (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        qos_spec = utils.find_resource(
-            volume_client.qos_specs, parsed_args.qos_spec
-        )
-
-        qos_associations = volume_client.qos_specs.get_associations(qos_spec)
-        if qos_associations:
-            associations = [
-                association.name for association in qos_associations
-            ]
-            qos_spec._info.update(
-                {'associations': format_columns.ListColumn(associations)}
-            )
-        qos_spec._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    qos_spec._info.pop('specs')
-                )
-            }
-        )
-
-        return zip(*sorted(qos_spec._info.items()))
-
-
-class UnsetQos(command.Command):
-    _description = _("Unset QoS specification properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'qos_spec',
-            metavar='<qos-spec>',
-            help=_('QoS specification to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key>',
-            action='append',
-            help=_(
-                'Property to remove from the QoS specification. '
-                '(repeat option to unset multiple properties)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        qos_spec = utils.find_resource(
-            volume_client.qos_specs, parsed_args.qos_spec
-        )
-
-        if parsed_args.property:
-            volume_client.qos_specs.unset_keys(
-                qos_spec.id, parsed_args.property
-            )
diff -pruN 7.4.0-3/openstackclient/volume/v1/service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/service.py
--- 7.4.0-3/openstackclient/volume/v1/service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/service.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,136 +0,0 @@
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Service action implementations"""
-
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-class ListService(command.Lister):
-    _description = _("List service command")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            "--host",
-            metavar="<host>",
-            help=_("List services on specified host (name only)"),
-        )
-        parser.add_argument(
-            "--service",
-            metavar="<service>",
-            help=_("List only specified service (name only)"),
-        )
-        parser.add_argument(
-            "--long",
-            action="store_true",
-            default=False,
-            help=_("List additional fields in output"),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        service_client = self.app.client_manager.volume
-
-        if parsed_args.long:
-            columns = [
-                "Binary",
-                "Host",
-                "Zone",
-                "Status",
-                "State",
-                "Updated At",
-                "Disabled Reason",
-            ]
-        else:
-            columns = [
-                "Binary",
-                "Host",
-                "Zone",
-                "Status",
-                "State",
-                "Updated At",
-            ]
-
-        data = service_client.services.list(
-            parsed_args.host, parsed_args.service
-        )
-        return (
-            columns,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                )
-                for s in data
-            ),
-        )
-
-
-class SetService(command.Command):
-    _description = _("Set volume service properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument("host", metavar="<host>", help=_("Name of host"))
-        parser.add_argument(
-            "service",
-            metavar="<service>",
-            help=_("Name of service (Binary name)"),
-        )
-        enabled_group = parser.add_mutually_exclusive_group()
-        enabled_group.add_argument(
-            "--enable", action="store_true", help=_("Enable volume service")
-        )
-        enabled_group.add_argument(
-            "--disable", action="store_true", help=_("Disable volume service")
-        )
-        parser.add_argument(
-            "--disable-reason",
-            metavar="<reason>",
-            help=_(
-                "Reason for disabling the service "
-                "(should be used with --disable option)"
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        if parsed_args.disable_reason and not parsed_args.disable:
-            msg = _(
-                "Cannot specify option --disable-reason without "
-                "--disable specified."
-            )
-            raise exceptions.CommandError(msg)
-
-        service_client = self.app.client_manager.volume
-        if parsed_args.enable:
-            service_client.services.enable(
-                parsed_args.host, parsed_args.service
-            )
-        if parsed_args.disable:
-            if parsed_args.disable_reason:
-                service_client.services.disable_log_reason(
-                    parsed_args.host,
-                    parsed_args.service,
-                    parsed_args.disable_reason,
-                )
-            else:
-                service_client.services.disable(
-                    parsed_args.host, parsed_args.service
-                )
diff -pruN 7.4.0-3/openstackclient/volume/v1/volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume.py
--- 7.4.0-3/openstackclient/volume/v1/volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,734 +0,0 @@
-#   Copyright 2012-2013 OpenStack Foundation
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Volume v1 Volume action implementations"""
-
-import argparse
-import functools
-import logging
-
-from cliff import columns as cliff_columns
-from osc_lib.cli import format_columns
-from osc_lib.cli import parseractions
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.common import pagination
-from openstackclient.i18n import _
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AttachmentsColumn(cliff_columns.FormattableColumn):
-    """Formattable column for attachments column.
-
-    Unlike the parent FormattableColumn class, the initializer of the
-    class takes server_cache as the second argument.
-    osc_lib.utils.get_item_properties instantiate cliff FormattableColumn
-    object with a single parameter "column value", so you need to pass
-    a partially initialized class like
-    ``functools.partial(AttachmentsColumn, server_cache)``.
-    """
-
-    def __init__(self, value, server_cache=None):
-        super().__init__(value)
-        self._server_cache = server_cache or {}
-
-    def human_readable(self):
-        """Return a formatted string of a volume's attached instances
-
-        :rtype: a string of formatted instances
-        """
-
-        msg = ''
-        for attachment in self._value:
-            server = attachment['server_id']
-            if server in self._server_cache.keys():
-                server = self._server_cache[server].name
-            device = attachment['device']
-            msg += f'Attached to {server} on {device} '
-        return msg
-
-
-def _check_size_arg(args):
-    """Check whether --size option is required or not.
-
-    Require size parameter only in case when snapshot or source
-    volume is not specified.
-    """
-
-    if (args.snapshot or args.source) is None and args.size is None:
-        msg = _(
-            "--size is a required option if snapshot "
-            "or source volume is not specified."
-        )
-        raise exceptions.CommandError(msg)
-
-
-class CreateVolume(command.ShowOne):
-    _description = _("Create new volume")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'name',
-            metavar='<name>',
-            help=_('Volume name'),
-        )
-        parser.add_argument(
-            '--size',
-            metavar='<size>',
-            type=int,
-            help=_(
-                "Volume size in GB (Required unless --snapshot or "
-                "--source is specified)"
-            ),
-        )
-        parser.add_argument(
-            '--type',
-            metavar='<volume-type>',
-            help=_("Set the type of volume"),
-        )
-        source_group = parser.add_mutually_exclusive_group()
-        source_group.add_argument(
-            '--image',
-            metavar='<image>',
-            help=_('Use <image> as source of volume (name or ID)'),
-        )
-        source_group.add_argument(
-            '--snapshot',
-            metavar='<snapshot>',
-            help=_('Use <snapshot> as source of volume (name or ID)'),
-        )
-        source_group.add_argument(
-            '--snapshot-id',
-            metavar='<snapshot-id>',
-            help=argparse.SUPPRESS,
-        )
-        source_group.add_argument(
-            '--source',
-            metavar='<volume>',
-            help=_('Volume to clone (name or ID)'),
-        )
-        parser.add_argument(
-            '--description',
-            metavar='<description>',
-            help=_('Volume description'),
-        )
-        parser.add_argument(
-            '--user',
-            metavar='<user>',
-            help=_('Specify an alternate user (name or ID)'),
-        )
-        parser.add_argument(
-            '--project',
-            metavar='<project>',
-            help=_('Specify an alternate project (name or ID)'),
-        )
-        parser.add_argument(
-            '--availability-zone',
-            metavar='<availability-zone>',
-            help=_('Create volume in <availability-zone>'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Set a property on this volume '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        bootable_group = parser.add_mutually_exclusive_group()
-        bootable_group.add_argument(
-            "--bootable",
-            action="store_true",
-            help=_("Mark volume as bootable"),
-        )
-        bootable_group.add_argument(
-            "--non-bootable",
-            action="store_true",
-            help=_("Mark volume as non-bootable (default)"),
-        )
-        readonly_group = parser.add_mutually_exclusive_group()
-        readonly_group.add_argument(
-            "--read-only",
-            action="store_true",
-            help=_("Set volume to read-only access mode"),
-        )
-        readonly_group.add_argument(
-            "--read-write",
-            action="store_true",
-            help=_("Set volume to read-write access mode (default)"),
-        )
-
-        return parser
-
-    def take_action(self, parsed_args):
-        _check_size_arg(parsed_args)
-        identity_client = self.app.client_manager.identity
-        image_client = self.app.client_manager.image
-        volume_client = self.app.client_manager.volume
-
-        source_volume = None
-        if parsed_args.source:
-            source_volume = utils.find_resource(
-                volume_client.volumes,
-                parsed_args.source,
-            ).id
-
-        project = None
-        if parsed_args.project:
-            project = utils.find_resource(
-                identity_client.tenants,
-                parsed_args.project,
-            ).id
-
-        user = None
-        if parsed_args.user:
-            user = utils.find_resource(
-                identity_client.users,
-                parsed_args.user,
-            ).id
-
-        image = None
-        if parsed_args.image:
-            image = image_client.find_image(
-                parsed_args.image,
-                ignore_missing=False,
-            ).id
-
-        snapshot = parsed_args.snapshot or parsed_args.snapshot_id
-
-        volume = volume_client.volumes.create(
-            parsed_args.size,
-            snapshot,
-            source_volume,
-            parsed_args.name,
-            parsed_args.description,
-            parsed_args.type,
-            user,
-            project,
-            parsed_args.availability_zone,
-            parsed_args.property,
-            image,
-        )
-
-        if parsed_args.bootable or parsed_args.non_bootable:
-            try:
-                if utils.wait_for_status(
-                    volume_client.volumes.get,
-                    volume.id,
-                    success_status=['available'],
-                    error_status=['error'],
-                    sleep_time=1,
-                ):
-                    volume_client.volumes.set_bootable(
-                        volume.id, parsed_args.bootable
-                    )
-                else:
-                    msg = _(
-                        "Volume status is not available for setting boot "
-                        "state"
-                    )
-                    raise exceptions.CommandError(msg)
-            except Exception as e:
-                LOG.error(_("Failed to set volume bootable property: %s"), e)
-        if parsed_args.read_only or parsed_args.read_write:
-            try:
-                if utils.wait_for_status(
-                    volume_client.volumes.get,
-                    volume.id,
-                    success_status=['available'],
-                    error_status=['error'],
-                    sleep_time=1,
-                ):
-                    volume_client.volumes.update_readonly_flag(
-                        volume.id, parsed_args.read_only
-                    )
-                else:
-                    msg = _(
-                        "Volume status is not available for setting it"
-                        "read only."
-                    )
-                    raise exceptions.CommandError(msg)
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to set volume read-only access "
-                        "mode flag: %s"
-                    ),
-                    e,
-                )
-
-        # Map 'metadata' column to 'properties'
-        volume._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    volume._info.pop('metadata')
-                ),
-                'type': volume._info.pop('volume_type'),
-            },
-        )
-        # Replace "display_name" by "name", keep consistent in v1 and v2
-        if 'display_name' in volume._info:
-            volume._info.update({'name': volume._info.pop('display_name')})
-        volume_info = utils.backward_compat_col_showone(
-            volume._info, parsed_args.columns, {'display_name': 'name'}
-        )
-
-        return zip(*sorted(volume_info.items()))
-
-
-class DeleteVolume(command.Command):
-    _description = _("Delete volume(s)")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volumes',
-            metavar='<volume>',
-            nargs="+",
-            help=_('Volume(s) to delete (name or ID)'),
-        )
-        parser.add_argument(
-            '--force',
-            action='store_true',
-            default=False,
-            help=_(
-                'Attempt forced removal of volume(s), regardless of state '
-                '(defaults to False)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        result = 0
-
-        for i in parsed_args.volumes:
-            try:
-                volume_obj = utils.find_resource(volume_client.volumes, i)
-                if parsed_args.force:
-                    volume_client.volumes.force_delete(volume_obj.id)
-                else:
-                    volume_client.volumes.delete(volume_obj.id)
-            except Exception as e:
-                result += 1
-                LOG.error(
-                    _(
-                        "Failed to delete volume with "
-                        "name or ID '%(volume)s': %(e)s"
-                    ),
-                    {'volume': i, 'e': e},
-                )
-
-        if result > 0:
-            total = len(parsed_args.volumes)
-            msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
-                'result': result,
-                'total': total,
-            }
-            raise exceptions.CommandError(msg)
-
-
-class ListVolume(command.Lister):
-    _description = _("List volumes")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            '--name',
-            metavar='<name>',
-            help=_('Filter results by volume name'),
-        )
-        parser.add_argument(
-            '--status',
-            metavar='<status>',
-            help=_('Filter results by status'),
-        )
-        parser.add_argument(
-            '--all-projects',
-            action='store_true',
-            default=False,
-            help=_('Include all projects (admin only)'),
-        )
-        parser.add_argument(
-            '--long',
-            action='store_true',
-            default=False,
-            help=_('List additional fields in output'),
-        )
-        pagination.add_offset_pagination_option_to_parser(parser)
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-
-        if parsed_args.long:
-            columns = (
-                'ID',
-                'Display Name',
-                'Status',
-                'Size',
-                'Volume Type',
-                'Bootable',
-                'Attachments',
-                'Metadata',
-            )
-            column_headers = (
-                'ID',
-                'Name',
-                'Status',
-                'Size',
-                'Type',
-                'Bootable',
-                'Attached to',
-                'Properties',
-            )
-        else:
-            columns = (
-                'ID',
-                'Display Name',
-                'Status',
-                'Size',
-                'Attachments',
-            )
-            column_headers = (
-                'ID',
-                'Name',
-                'Status',
-                'Size',
-                'Attached to',
-            )
-
-        # Cache the server list
-        server_cache = {}
-        try:
-            compute_client = self.app.client_manager.sdk_connection.compute
-            for s in compute_client.servers():
-                server_cache[s.id] = s
-        except Exception:  # noqa: S110
-            # Just forget it if there's any trouble
-            pass
-        AttachmentsColumnWithCache = functools.partial(
-            AttachmentsColumn, server_cache=server_cache
-        )
-
-        search_opts = {
-            'all_tenants': parsed_args.all_projects,
-            'display_name': parsed_args.name,
-            'status': parsed_args.status,
-        }
-
-        if parsed_args.offset:
-            search_opts['offset'] = parsed_args.offset
-
-        data = volume_client.volumes.list(
-            search_opts=search_opts,
-            limit=parsed_args.limit,
-        )
-        column_headers = utils.backward_compat_col_lister(
-            column_headers, parsed_args.columns, {'Display Name': 'Name'}
-        )
-
-        return (
-            column_headers,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                    formatters={
-                        'Metadata': format_columns.DictColumn,
-                        'Attachments': AttachmentsColumnWithCache,
-                    },
-                )
-                for s in data
-            ),
-        )
-
-
-class MigrateVolume(command.Command):
-    _description = _("Migrate volume to a new host")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume',
-            metavar="<volume>",
-            help=_("Volume to migrate (name or ID)"),
-        )
-        parser.add_argument(
-            '--host',
-            metavar="<host>",
-            required=True,
-            help=_(
-                "Destination host (takes the form: host@backend-name#pool)"
-            ),
-        )
-        parser.add_argument(
-            '--force-host-copy',
-            action="store_true",
-            help=_(
-                "Enable generic host-based force-migration, "
-                "which bypasses driver optimizations"
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
-        volume_client.volumes.migrate_volume(
-            volume.id,
-            parsed_args.host,
-            parsed_args.force_host_copy,
-        )
-
-
-class SetVolume(command.Command):
-    _description = _("Set volume properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume',
-            metavar='<volume>',
-            help=_('Volume to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--name',
-            metavar='<name>',
-            help=_('New volume name'),
-        )
-        parser.add_argument(
-            '--description',
-            metavar='<description>',
-            help=_('New volume description'),
-        )
-        parser.add_argument(
-            '--size',
-            metavar='<size>',
-            type=int,
-            help=_('Extend volume size in GB'),
-        )
-        parser.add_argument(
-            "--no-property",
-            dest="no_property",
-            action="store_true",
-            help=_(
-                "Remove all properties from <volume> "
-                "(specify both --no-property and --property to "
-                "remove the current properties before setting "
-                "new properties.)"
-            ),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Set a property on this volume '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        bootable_group = parser.add_mutually_exclusive_group()
-        bootable_group.add_argument(
-            "--bootable",
-            action="store_true",
-            help=_("Mark volume as bootable"),
-        )
-        bootable_group.add_argument(
-            "--non-bootable",
-            action="store_true",
-            help=_("Mark volume as non-bootable"),
-        )
-        readonly_group = parser.add_mutually_exclusive_group()
-        readonly_group.add_argument(
-            "--read-only",
-            action="store_true",
-            help=_("Set volume to read-only access mode"),
-        )
-        readonly_group.add_argument(
-            "--read-write",
-            action="store_true",
-            help=_("Set volume to read-write access mode"),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
-
-        result = 0
-        if parsed_args.size:
-            try:
-                if volume.status != 'available':
-                    msg = (
-                        _(
-                            "Volume is in %s state, it must be available "
-                            "before size can be extended"
-                        )
-                        % volume.status
-                    )
-                    raise exceptions.CommandError(msg)
-                if parsed_args.size <= volume.size:
-                    msg = (
-                        _("New size must be greater than %s GB") % volume.size
-                    )
-                    raise exceptions.CommandError(msg)
-                volume_client.volumes.extend(volume.id, parsed_args.size)
-            except Exception as e:
-                LOG.error(_("Failed to set volume size: %s"), e)
-                result += 1
-
-        if parsed_args.no_property:
-            try:
-                volume_client.volumes.delete_metadata(
-                    volume.id, volume.metadata.keys()
-                )
-            except Exception as e:
-                LOG.error(_("Failed to clean volume properties: %s"), e)
-                result += 1
-
-        if parsed_args.property:
-            try:
-                volume_client.volumes.set_metadata(
-                    volume.id, parsed_args.property
-                )
-            except Exception as e:
-                LOG.error(_("Failed to set volume property: %s"), e)
-                result += 1
-        if parsed_args.bootable or parsed_args.non_bootable:
-            try:
-                volume_client.volumes.set_bootable(
-                    volume.id, parsed_args.bootable
-                )
-            except Exception as e:
-                LOG.error(_("Failed to set volume bootable property: %s"), e)
-                result += 1
-        if parsed_args.read_only or parsed_args.read_write:
-            try:
-                volume_client.volumes.update_readonly_flag(
-                    volume.id, parsed_args.read_only
-                )
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to set volume read-only access "
-                        "mode flag: %s"
-                    ),
-                    e,
-                )
-                result += 1
-        kwargs = {}
-        if parsed_args.name:
-            kwargs['display_name'] = parsed_args.name
-        if parsed_args.description:
-            kwargs['display_description'] = parsed_args.description
-        if kwargs:
-            try:
-                volume_client.volumes.update(volume.id, **kwargs)
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to update volume display name "
-                        "or display description: %s"
-                    ),
-                    e,
-                )
-                result += 1
-
-        if result > 0:
-            raise exceptions.CommandError(
-                _("One or more of the " "set operations failed")
-            )
-
-
-class ShowVolume(command.ShowOne):
-    _description = _("Show volume details")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume',
-            metavar='<volume>',
-            help=_('Volume to display (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
-        # Map 'metadata' column to 'properties'
-        volume._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    volume._info.pop('metadata')
-                ),
-                'type': volume._info.pop('volume_type'),
-            },
-        )
-        if 'os-vol-tenant-attr:tenant_id' in volume._info:
-            volume._info.update(
-                {
-                    'project_id': volume._info.pop(
-                        'os-vol-tenant-attr:tenant_id'
-                    )
-                }
-            )
-        # Replace "display_name" by "name", keep consistent in v1 and v2
-        if 'display_name' in volume._info:
-            volume._info.update({'name': volume._info.pop('display_name')})
-
-        volume_info = utils.backward_compat_col_showone(
-            volume._info, parsed_args.columns, {'display_name': 'name'}
-        )
-
-        return zip(*sorted(volume_info.items()))
-
-
-class UnsetVolume(command.Command):
-    _description = _("Unset volume properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume',
-            metavar='<volume>',
-            help=_('Volume to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key>',
-            action='append',
-            help=_(
-                'Remove a property from volume '
-                '(repeat option to remove multiple properties)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
-
-        if parsed_args.property:
-            volume_client.volumes.delete_metadata(
-                volume.id,
-                parsed_args.property,
-            )
diff -pruN 7.4.0-3/openstackclient/volume/v1/volume_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_backup.py
--- 7.4.0-3/openstackclient/volume/v1/volume_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_backup.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,302 +0,0 @@
-#   Copyright 2012-2013 OpenStack Foundation
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Volume v1 Backup action implementations"""
-
-import copy
-import functools
-import logging
-
-from cliff import columns as cliff_columns
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-LOG = logging.getLogger(__name__)
-
-
-class VolumeIdColumn(cliff_columns.FormattableColumn):
-    """Formattable column for volume ID column.
-
-    Unlike the parent FormattableColumn class, the initializer of the
-    class takes volume_cache as the second argument.
-    osc_lib.utils.get_item_properties instantiate cliff FormattableColumn
-    object with a single parameter "column value", so you need to pass
-    a partially initialized class like
-    ``functools.partial(VolumeIdColumn, volume_cache)``.
-    """
-
-    def __init__(self, value, volume_cache=None):
-        super().__init__(value)
-        self._volume_cache = volume_cache or {}
-
-    def human_readable(self):
-        """Return a volume name if available
-
-        :rtype: either the volume ID or name
-        """
-        volume_id = self._value
-        volume = volume_id
-        if volume_id in self._volume_cache.keys():
-            volume = self._volume_cache[volume_id].display_name
-        return volume
-
-
-class CreateVolumeBackup(command.ShowOne):
-    _description = _("Create new volume backup")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume',
-            metavar='<volume>',
-            help=_('Volume to backup (name or ID)'),
-        )
-        parser.add_argument(
-            '--container',
-            metavar='<container>',
-            required=False,
-            help=_('Optional backup container name'),
-        )
-        parser.add_argument(
-            '--name',
-            metavar='<name>',
-            help=_('Name of the backup'),
-        )
-        parser.add_argument(
-            '--description',
-            metavar='<description>',
-            help=_('Description of the backup'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_id = utils.find_resource(
-            volume_client.volumes, parsed_args.volume
-        ).id
-        backup = volume_client.backups.create(
-            volume_id,
-            parsed_args.container,
-            parsed_args.name,
-            parsed_args.description,
-        )
-
-        backup._info.pop('links')
-        return zip(*sorted(backup._info.items()))
-
-
-class DeleteVolumeBackup(command.Command):
-    _description = _("Delete volume backup(s)")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'backups',
-            metavar='<backup>',
-            nargs="+",
-            help=_('Backup(s) to delete (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        result = 0
-
-        for i in parsed_args.backups:
-            try:
-                backup_id = utils.find_resource(volume_client.backups, i).id
-                volume_client.backups.delete(backup_id)
-            except Exception as e:
-                result += 1
-                LOG.error(
-                    _(
-                        "Failed to delete backup with "
-                        "name or ID '%(backup)s': %(e)s"
-                    ),
-                    {'backup': i, 'e': e},
-                )
-
-        if result > 0:
-            total = len(parsed_args.backups)
-            msg = _("%(result)s of %(total)s backups failed " "to delete.") % {
-                'result': result,
-                'total': total,
-            }
-            raise exceptions.CommandError(msg)
-
-
-class ListVolumeBackup(command.Lister):
-    _description = _("List volume backups")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            '--long',
-            action='store_true',
-            default=False,
-            help=_('List additional fields in output'),
-        )
-        parser.add_argument(
-            "--name",
-            metavar="<name>",
-            help=_("Filters results by the backup name"),
-        )
-        parser.add_argument(
-            "--status",
-            metavar="<status>",
-            choices=[
-                'creating',
-                'available',
-                'deleting',
-                'error',
-                'restoring',
-                'error_restoring',
-            ],
-            help=_(
-                "Filters results by the backup status "
-                "('creating', 'available', 'deleting', "
-                "'error', 'restoring' or 'error_restoring')"
-            ),
-        )
-        parser.add_argument(
-            "--volume",
-            metavar="<volume>",
-            help=_(
-                "Filters results by the volume which they "
-                "backup (name or ID)"
-            ),
-        )
-        parser.add_argument(
-            '--all-projects',
-            action='store_true',
-            default=False,
-            help=_('Include all projects (admin only)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-
-        if parsed_args.long:
-            columns = [
-                'ID',
-                'Name',
-                'Description',
-                'Status',
-                'Size',
-                'Availability Zone',
-                'Volume ID',
-                'Container',
-            ]
-            column_headers = copy.deepcopy(columns)
-            column_headers[6] = 'Volume'
-        else:
-            columns = ['ID', 'Name', 'Description', 'Status', 'Size']
-            column_headers = columns
-
-        # Cache the volume list
-        volume_cache = {}
-        try:
-            for s in volume_client.volumes.list():
-                volume_cache[s.id] = s
-        except Exception:  # noqa: S110
-            # Just forget it if there's any trouble
-            pass
-        VolumeIdColumnWithCache = functools.partial(
-            VolumeIdColumn, volume_cache=volume_cache
-        )
-
-        filter_volume_id = None
-        if parsed_args.volume:
-            filter_volume_id = utils.find_resource(
-                volume_client.volumes, parsed_args.volume
-            ).id
-        search_opts = {
-            'name': parsed_args.name,
-            'status': parsed_args.status,
-            'volume_id': filter_volume_id,
-            'all_tenants': parsed_args.all_projects,
-        }
-        data = volume_client.backups.list(
-            search_opts=search_opts,
-        )
-
-        return (
-            column_headers,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                    formatters={'Volume ID': VolumeIdColumnWithCache},
-                )
-                for s in data
-            ),
-        )
-
-
-class RestoreVolumeBackup(command.Command):
-    _description = _("Restore volume backup")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'backup',
-            metavar='<backup>',
-            help=_('Backup to restore (name or ID)'),
-        )
-        parser.add_argument(
-            'volume',
-            metavar='<volume>',
-            nargs='?',
-            help=_('Volume to restore to (name or ID) (default to None)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        backup = utils.find_resource(
-            volume_client.backups,
-            parsed_args.backup,
-        )
-        volume_id = None
-        if parsed_args.volume is not None:
-            volume_id = utils.find_resource(
-                volume_client.volumes,
-                parsed_args.volume,
-            ).id
-        return volume_client.restores.restore(backup.id, volume_id)
-
-
-class ShowVolumeBackup(command.ShowOne):
-    _description = _("Display volume backup details")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'backup',
-            metavar='<backup>',
-            help=_('Backup to display (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        backup = utils.find_resource(volume_client.backups, parsed_args.backup)
-        backup._info.pop('links')
-        return zip(*sorted(backup._info.items()))
diff -pruN 7.4.0-3/openstackclient/volume/v1/volume_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_snapshot.py
--- 7.4.0-3/openstackclient/volume/v1/volume_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_snapshot.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,433 +0,0 @@
-#   Copyright 2012-2013 OpenStack Foundation
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Volume v1 Snapshot action implementations"""
-
-import copy
-import functools
-import logging
-
-from cliff import columns as cliff_columns
-from osc_lib.cli import format_columns
-from osc_lib.cli import parseractions
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-LOG = logging.getLogger(__name__)
-
-
-class VolumeIdColumn(cliff_columns.FormattableColumn):
-    """Formattable column for volume ID column.
-
-    Unlike the parent FormattableColumn class, the initializer of the
-    class takes volume_cache as the second argument.
-    osc_lib.utils.get_item_properties instantiate cliff FormattableColumn
-    object with a single parameter "column value", so you need to pass
-    a partially initialized class like
-    ``functools.partial(VolumeIdColumn, volume_cache)``.
-    """
-
-    def __init__(self, value, volume_cache=None):
-        super().__init__(value)
-        self._volume_cache = volume_cache or {}
-
-    def human_readable(self):
-        """Return a volume name if available
-
-        :rtype: either the volume ID or name
-        """
-        volume_id = self._value
-        volume = volume_id
-        if volume_id in self._volume_cache.keys():
-            volume = self._volume_cache[volume_id].display_name
-        return volume
-
-
-class CreateVolumeSnapshot(command.ShowOne):
-    _description = _("Create new volume snapshot")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'snapshot_name',
-            metavar='<snapshot-name>',
-            help=_('Name of the new snapshot'),
-        )
-        parser.add_argument(
-            '--volume',
-            metavar='<volume>',
-            help=_(
-                'Volume to snapshot (name or ID) '
-                '(default is <snapshot-name>)'
-            ),
-        )
-        parser.add_argument(
-            '--description',
-            metavar='<description>',
-            help=_('Description of the snapshot'),
-        )
-        parser.add_argument(
-            '--force',
-            dest='force',
-            action='store_true',
-            default=False,
-            help=_(
-                'Create a snapshot attached to an instance. '
-                'Default is False'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume = parsed_args.volume
-        if not parsed_args.volume:
-            volume = parsed_args.snapshot_name
-        volume_id = utils.find_resource(volume_client.volumes, volume).id
-        snapshot = volume_client.volume_snapshots.create(
-            volume_id,
-            parsed_args.force,
-            parsed_args.snapshot_name,
-            parsed_args.description,
-        )
-
-        snapshot._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    snapshot._info.pop('metadata')
-                )
-            }
-        )
-
-        return zip(*sorted(snapshot._info.items()))
-
-
-class DeleteVolumeSnapshot(command.Command):
-    _description = _("Delete volume snapshot(s)")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'snapshots',
-            metavar='<snapshot>',
-            nargs="+",
-            help=_('Snapshot(s) to delete (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        result = 0
-
-        for i in parsed_args.snapshots:
-            try:
-                snapshot_id = utils.find_resource(
-                    volume_client.volume_snapshots, i
-                ).id
-                volume_client.volume_snapshots.delete(snapshot_id)
-            except Exception as e:
-                result += 1
-                LOG.error(
-                    _(
-                        "Failed to delete snapshot with "
-                        "name or ID '%(snapshot)s': %(e)s"
-                    ),
-                    {'snapshot': i, 'e': e},
-                )
-
-        if result > 0:
-            total = len(parsed_args.snapshots)
-            msg = _(
-                "%(result)s of %(total)s snapshots failed " "to delete."
-            ) % {'result': result, 'total': total}
-            raise exceptions.CommandError(msg)
-
-
-class ListVolumeSnapshot(command.Lister):
-    _description = _("List volume snapshots")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            '--all-projects',
-            action='store_true',
-            default=False,
-            help=_('Include all projects (admin only)'),
-        )
-        parser.add_argument(
-            '--long',
-            action='store_true',
-            default=False,
-            help=_('List additional fields in output'),
-        )
-        parser.add_argument(
-            '--name',
-            metavar='<name>',
-            default=None,
-            help=_('Filters results by a name.'),
-        )
-        parser.add_argument(
-            '--status',
-            metavar='<status>',
-            choices=[
-                'available',
-                'error',
-                'creating',
-                'deleting',
-                'error_deleting',
-            ],
-            help=_(
-                "Filters results by a status. "
-                "('available', 'error', 'creating', 'deleting'"
-                " or 'error_deleting')"
-            ),
-        )
-        parser.add_argument(
-            '--volume',
-            metavar='<volume>',
-            default=None,
-            help=_('Filters results by a volume (name or ID).'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-
-        if parsed_args.long:
-            columns = [
-                'ID',
-                'Display Name',
-                'Display Description',
-                'Status',
-                'Size',
-                'Created At',
-                'Volume ID',
-                'Metadata',
-            ]
-            column_headers = copy.deepcopy(columns)
-            column_headers[6] = 'Volume'
-            column_headers[7] = 'Properties'
-        else:
-            columns = [
-                'ID',
-                'Display Name',
-                'Display Description',
-                'Status',
-                'Size',
-            ]
-            column_headers = copy.deepcopy(columns)
-
-        # Always update Name and Description
-        column_headers[1] = 'Name'
-        column_headers[2] = 'Description'
-
-        # Cache the volume list
-        volume_cache = {}
-        try:
-            for s in volume_client.volumes.list():
-                volume_cache[s.id] = s
-        except Exception:  # noqa: S110
-            # Just forget it if there's any trouble
-            pass
-        VolumeIdColumnWithCache = functools.partial(
-            VolumeIdColumn, volume_cache=volume_cache
-        )
-
-        volume_id = None
-        if parsed_args.volume:
-            volume_id = utils.find_resource(
-                volume_client.volumes, parsed_args.volume
-            ).id
-
-        search_opts = {
-            'all_tenants': parsed_args.all_projects,
-            'display_name': parsed_args.name,
-            'status': parsed_args.status,
-            'volume_id': volume_id,
-        }
-
-        data = volume_client.volume_snapshots.list(search_opts=search_opts)
-        return (
-            column_headers,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                    formatters={
-                        'Metadata': format_columns.DictColumn,
-                        'Volume ID': VolumeIdColumnWithCache,
-                    },
-                )
-                for s in data
-            ),
-        )
-
-
-class SetVolumeSnapshot(command.Command):
-    _description = _("Set volume snapshot properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'snapshot',
-            metavar='<snapshot>',
-            help=_('Snapshot to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--name', metavar='<name>', help=_('New snapshot name')
-        )
-        parser.add_argument(
-            '--description',
-            metavar='<description>',
-            help=_('New snapshot description'),
-        )
-        parser.add_argument(
-            "--no-property",
-            dest="no_property",
-            action="store_true",
-            help=_(
-                "Remove all properties from <snapshot> "
-                "(specify both --no-property and --property to "
-                "remove the current properties before setting "
-                "new properties.)"
-            ),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Property to add/change for this snapshot '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        snapshot = utils.find_resource(
-            volume_client.volume_snapshots, parsed_args.snapshot
-        )
-
-        result = 0
-        if parsed_args.no_property:
-            try:
-                key_list = snapshot.metadata.keys()
-                volume_client.volume_snapshots.delete_metadata(
-                    snapshot.id,
-                    list(key_list),
-                )
-            except Exception as e:
-                LOG.error(_("Failed to clean snapshot properties: %s"), e)
-                result += 1
-
-        if parsed_args.property:
-            try:
-                volume_client.volume_snapshots.set_metadata(
-                    snapshot.id, parsed_args.property
-                )
-            except Exception as e:
-                LOG.error(_("Failed to set snapshot property: %s"), e)
-                result += 1
-
-        kwargs = {}
-        if parsed_args.name:
-            kwargs['display_name'] = parsed_args.name
-        if parsed_args.description:
-            kwargs['display_description'] = parsed_args.description
-        if kwargs:
-            try:
-                snapshot.update(**kwargs)
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to update snapshot display name "
-                        "or display description: %s"
-                    ),
-                    e,
-                )
-                result += 1
-
-        if result > 0:
-            raise exceptions.CommandError(
-                _("One or more of the " "set operations failed")
-            )
-
-
-class ShowVolumeSnapshot(command.ShowOne):
-    _description = _("Display volume snapshot details")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'snapshot',
-            metavar='<snapshot>',
-            help=_('Snapshot to display (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        snapshot = utils.find_resource(
-            volume_client.volume_snapshots, parsed_args.snapshot
-        )
-
-        snapshot._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    snapshot._info.pop('metadata')
-                )
-            }
-        )
-
-        return zip(*sorted(snapshot._info.items()))
-
-
-class UnsetVolumeSnapshot(command.Command):
-    _description = _("Unset volume snapshot properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'snapshot',
-            metavar='<snapshot>',
-            help=_('Snapshot to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key>',
-            action='append',
-            help=_(
-                'Property to remove from snapshot '
-                '(repeat option to remove multiple properties)'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        snapshot = utils.find_resource(
-            volume_client.volume_snapshots, parsed_args.snapshot
-        )
-
-        if parsed_args.property:
-            volume_client.volume_snapshots.delete_metadata(
-                snapshot.id,
-                parsed_args.property,
-            )
diff -pruN 7.4.0-3/openstackclient/volume/v1/volume_transfer_request.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_transfer_request.py
--- 7.4.0-3/openstackclient/volume/v1/volume_transfer_request.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_transfer_request.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,200 +0,0 @@
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Volume v1 transfer action implementations"""
-
-import logging
-
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AcceptTransferRequest(command.ShowOne):
-    _description = _("Accept volume transfer request.")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'transfer_request',
-            metavar="<transfer-request-id>",
-            help=_('Volume transfer request to accept (ID only)'),
-        )
-        parser.add_argument(
-            '--auth-key',
-            metavar="<key>",
-            help=_('Volume transfer request authentication key'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-
-        try:
-            transfer_request_id = utils.find_resource(
-                volume_client.transfers, parsed_args.transfer_request
-            ).id
-        except exceptions.CommandError:
-            # Non-admin users will fail to lookup name -> ID so we just
-            # move on and attempt with the user-supplied information
-            transfer_request_id = parsed_args.transfer_request
-
-        if not parsed_args.auth_key:
-            msg = _("argument --auth-key is required")
-            raise exceptions.CommandError(msg)
-
-        transfer_accept = volume_client.transfers.accept(
-            transfer_request_id,
-            parsed_args.auth_key,
-        )
-        transfer_accept._info.pop("links", None)
-
-        return zip(*sorted(transfer_accept._info.items()))
-
-
-class CreateTransferRequest(command.ShowOne):
-    _description = _("Create volume transfer request.")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            '--name',
-            metavar="<name>",
-            help=_('New transfer request name (default to None)'),
-        )
-        parser.add_argument(
-            'volume',
-            metavar="<volume>",
-            help=_('Volume to transfer (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_id = utils.find_resource(
-            volume_client.volumes,
-            parsed_args.volume,
-        ).id
-        volume_transfer_request = volume_client.transfers.create(
-            volume_id,
-            parsed_args.name,
-        )
-        volume_transfer_request._info.pop("links", None)
-
-        return zip(*sorted(volume_transfer_request._info.items()))
-
-
-class DeleteTransferRequest(command.Command):
-    _description = _("Delete volume transfer request(s).")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'transfer_request',
-            metavar="<transfer-request>",
-            nargs="+",
-            help=_('Volume transfer request(s) to delete (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        result = 0
-
-        for t in parsed_args.transfer_request:
-            try:
-                transfer_request_id = utils.find_resource(
-                    volume_client.transfers,
-                    t,
-                ).id
-                volume_client.transfers.delete(transfer_request_id)
-            except Exception as e:
-                result += 1
-                LOG.error(
-                    _(
-                        "Failed to delete volume transfer request "
-                        "with name or ID '%(transfer)s': %(e)s"
-                    )
-                    % {'transfer': t, 'e': e}
-                )
-
-        if result > 0:
-            total = len(parsed_args.transfer_request)
-            msg = _(
-                "%(result)s of %(total)s volume transfer requests failed"
-                " to delete"
-            ) % {'result': result, 'total': total}
-            raise exceptions.CommandError(msg)
-
-
-class ListTransferRequest(command.Lister):
-    _description = _("Lists all volume transfer requests.")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            '--all-projects',
-            dest='all_projects',
-            action="store_true",
-            default=False,
-            help=_('Include all projects (admin only)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        columns = ['ID', 'Name', 'Volume ID']
-        column_headers = ['ID', 'Name', 'Volume']
-
-        volume_client = self.app.client_manager.volume
-
-        volume_transfer_result = volume_client.transfers.list(
-            detailed=True,
-            search_opts={'all_tenants': parsed_args.all_projects},
-        )
-
-        return (
-            column_headers,
-            (
-                utils.get_item_properties(s, columns)
-                for s in volume_transfer_result
-            ),
-        )
-
-
-class ShowTransferRequest(command.ShowOne):
-    _description = _("Show volume transfer request details.")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'transfer_request',
-            metavar="<transfer-request>",
-            help=_('Volume transfer request to display (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_transfer_request = utils.find_resource(
-            volume_client.transfers,
-            parsed_args.transfer_request,
-        )
-        volume_transfer_request._info.pop("links", None)
-
-        return zip(*sorted(volume_transfer_request._info.items()))
diff -pruN 7.4.0-3/openstackclient/volume/v1/volume_type.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_type.py
--- 7.4.0-3/openstackclient/volume/v1/volume_type.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v1/volume_type.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,520 +0,0 @@
-#   Copyright 2012-2013 OpenStack Foundation
-#
-#   Licensed under the Apache License, Version 2.0 (the "License"); you may
-#   not use this file except in compliance with the License. You may obtain
-#   a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#   License for the specific language governing permissions and limitations
-#   under the License.
-#
-
-"""Volume v1 Type action implementations"""
-
-import functools
-import logging
-
-from cliff import columns as cliff_columns
-from osc_lib.cli import format_columns
-from osc_lib.cli import parseractions
-from osc_lib.command import command
-from osc_lib import exceptions
-from osc_lib import utils
-
-from openstackclient.i18n import _
-
-
-LOG = logging.getLogger(__name__)
-
-
-class EncryptionInfoColumn(cliff_columns.FormattableColumn):
-    """Formattable column for encryption info column.
-
-    Unlike the parent FormattableColumn class, the initializer of the
-    class takes encryption_data as the second argument.
-    osc_lib.utils.get_item_properties instantiate cliff FormattableColumn
-    object with a single parameter "column value", so you need to pass
-    a partially initialized class like
-    ``functools.partial(EncryptionInfoColumn encryption_data)``.
-    """
-
-    def __init__(self, value, encryption_data=None):
-        super().__init__(value)
-        self._encryption_data = encryption_data or {}
-
-    def _get_encryption_info(self):
-        type_id = self._value
-        return self._encryption_data.get(type_id)
-
-    def human_readable(self):
-        encryption_info = self._get_encryption_info()
-        if encryption_info:
-            return utils.format_dict(encryption_info)
-        else:
-            return '-'
-
-    def machine_readable(self):
-        return self._get_encryption_info()
-
-
-def _create_encryption_type(volume_client, volume_type, parsed_args):
-    if not parsed_args.encryption_provider:
-        msg = _(
-            "'--encryption-provider' should be specified while "
-            "creating a new encryption type"
-        )
-        raise exceptions.CommandError(msg)
-    # set the default of control location while creating
-    control_location = 'front-end'
-    if parsed_args.encryption_control_location:
-        control_location = parsed_args.encryption_control_location
-    body = {
-        'provider': parsed_args.encryption_provider,
-        'cipher': parsed_args.encryption_cipher,
-        'key_size': parsed_args.encryption_key_size,
-        'control_location': control_location,
-    }
-    encryption = volume_client.volume_encryption_types.create(
-        volume_type, body
-    )
-    return encryption
-
-
-class CreateVolumeType(command.ShowOne):
-    _description = _("Create new volume type")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'name',
-            metavar='<name>',
-            help=_('Volume type name'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Set a property on this volume type '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
-        parser.add_argument(
-            '--encryption-provider',
-            metavar='<provider>',
-            help=_(
-                'Set the encryption provider format for '
-                'this volume type (e.g "luks" or "plain") (admin only) '
-                '(This option is required when setting encryption type '
-                'of a volume. Consider using other encryption options '
-                'such as: "--encryption-cipher", "--encryption-key-size" '
-                'and "--encryption-control-location")'
-            ),
-        )
-        parser.add_argument(
-            '--encryption-cipher',
-            metavar='<cipher>',
-            help=_(
-                'Set the encryption algorithm or mode for this '
-                'volume type (e.g "aes-xts-plain64") (admin only)'
-            ),
-        )
-        parser.add_argument(
-            '--encryption-key-size',
-            metavar='<key-size>',
-            type=int,
-            help=_(
-                'Set the size of the encryption key of this '
-                'volume type (e.g "128" or "256") (admin only)'
-            ),
-        )
-        parser.add_argument(
-            '--encryption-control-location',
-            metavar='<control-location>',
-            choices=['front-end', 'back-end'],
-            help=_(
-                'Set the notional service where the encryption is '
-                'performed ("front-end" or "back-end") (admin only) '
-                '(The default value for this option is "front-end" '
-                'when setting encryption type of a volume. Consider '
-                'using other encryption options such as: '
-                '"--encryption-cipher", "--encryption-key-size" and '
-                '"--encryption-provider")'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_type = volume_client.volume_types.create(parsed_args.name)
-        volume_type._info.pop('extra_specs')
-        if parsed_args.property:
-            result = volume_type.set_keys(parsed_args.property)
-            volume_type._info.update(
-                {'properties': format_columns.DictColumn(result)}
-            )
-        if (
-            parsed_args.encryption_provider
-            or parsed_args.encryption_cipher
-            or parsed_args.encryption_key_size
-            or parsed_args.encryption_control_location
-        ):
-            try:
-                # create new encryption
-                encryption = _create_encryption_type(
-                    volume_client, volume_type, parsed_args
-                )
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to set encryption information for this "
-                        "volume type: %s"
-                    ),
-                    e,
-                )
-            # add encryption info in result
-            encryption._info.pop("volume_type_id", None)
-            volume_type._info.update(
-                {'encryption': format_columns.DictColumn(encryption._info)}
-            )
-        volume_type._info.pop("os-volume-type-access:is_public", None)
-
-        return zip(*sorted(volume_type._info.items()))
-
-
-class DeleteVolumeType(command.Command):
-    _description = _("Delete volume type(s)")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume_types',
-            metavar='<volume-type>',
-            nargs='+',
-            help=_('Volume type(s) to delete (name or ID)'),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        result = 0
-
-        for volume_type in parsed_args.volume_types:
-            try:
-                vol_type = utils.find_resource(
-                    volume_client.volume_types, volume_type
-                )
-
-                volume_client.volume_types.delete(vol_type)
-            except Exception as e:
-                result += 1
-                LOG.error(
-                    _(
-                        "Failed to delete volume type with "
-                        "name or ID '%(volume_type)s': %(e)s"
-                    )
-                    % {'volume_type': volume_type, 'e': e}
-                )
-
-        if result > 0:
-            total = len(parsed_args.volume_types)
-            msg = _(
-                "%(result)s of %(total)s volume types failed " "to delete."
-            ) % {'result': result, 'total': total}
-            raise exceptions.CommandError(msg)
-
-
-class ListVolumeType(command.Lister):
-    _description = _("List volume types")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            '--long',
-            action='store_true',
-            default=False,
-            help=_('List additional fields in output'),
-        )
-        parser.add_argument(
-            "--encryption-type",
-            action="store_true",
-            help=_(
-                "Display encryption information for each volume type "
-                "(admin only)"
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        if parsed_args.long:
-            columns = ['ID', 'Name', 'Is Public', 'Extra Specs']
-            column_headers = ['ID', 'Name', 'Is Public', 'Properties']
-        else:
-            columns = ['ID', 'Name', 'Is Public']
-            column_headers = ['ID', 'Name', 'Is Public']
-        data = volume_client.volume_types.list()
-
-        formatters = {'Extra Specs': format_columns.DictColumn}
-
-        if parsed_args.encryption_type:
-            encryption = {}
-            for d in volume_client.volume_encryption_types.list():
-                volume_type_id = d._info['volume_type_id']
-                # remove some redundant information
-                del_key = [
-                    'deleted',
-                    'created_at',
-                    'updated_at',
-                    'deleted_at',
-                    'volume_type_id',
-                ]
-                for key in del_key:
-                    d._info.pop(key, None)
-                # save the encryption information with their volume type ID
-                encryption[volume_type_id] = d._info
-            # We need to get volume type ID, then show encryption
-            # information according to the ID, so use "id" to keep
-            # difference to the real "ID" column.
-            columns += ['id']
-            column_headers += ['Encryption']
-
-            _EncryptionInfoColumn = functools.partial(
-                EncryptionInfoColumn, encryption_data=encryption
-            )
-            formatters['id'] = _EncryptionInfoColumn
-
-        return (
-            column_headers,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                    formatters=formatters,
-                )
-                for s in data
-            ),
-        )
-
-
-class SetVolumeType(command.Command):
-    _description = _("Set volume type properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume_type',
-            metavar='<volume-type>',
-            help=_('Volume type to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key=value>',
-            action=parseractions.KeyValueAction,
-            help=_(
-                'Set a property on this volume type '
-                '(repeat option to set multiple properties)'
-            ),
-        )
-        # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
-        parser.add_argument(
-            '--encryption-provider',
-            metavar='<provider>',
-            help=_(
-                'Set the encryption provider format for '
-                'this volume type (e.g "luks" or "plain") (admin only) '
-                '(This option is required when setting encryption type '
-                'of a volume. Consider using other encryption options '
-                'such as: "--encryption-cipher", "--encryption-key-size" '
-                'and "--encryption-control-location")'
-            ),
-        )
-        parser.add_argument(
-            '--encryption-cipher',
-            metavar='<cipher>',
-            help=_(
-                'Set the encryption algorithm or mode for this '
-                'volume type (e.g "aes-xts-plain64") (admin only)'
-            ),
-        )
-        parser.add_argument(
-            '--encryption-key-size',
-            metavar='<key-size>',
-            type=int,
-            help=_(
-                'Set the size of the encryption key of this '
-                'volume type (e.g "128" or "256") (admin only)'
-            ),
-        )
-        parser.add_argument(
-            '--encryption-control-location',
-            metavar='<control-location>',
-            choices=['front-end', 'back-end'],
-            help=_(
-                'Set the notional service where the encryption is '
-                'performed ("front-end" or "back-end") (admin only) '
-                '(The default value for this option is "front-end" '
-                'when setting encryption type of a volume. Consider '
-                'using other encryption options such as: '
-                '"--encryption-cipher", "--encryption-key-size" and '
-                '"--encryption-provider")'
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_type = utils.find_resource(
-            volume_client.volume_types, parsed_args.volume_type
-        )
-
-        result = 0
-        if parsed_args.property:
-            try:
-                volume_type.set_keys(parsed_args.property)
-            except Exception as e:
-                LOG.error(_("Failed to set volume type property: %s"), e)
-                result += 1
-
-        if (
-            parsed_args.encryption_provider
-            or parsed_args.encryption_cipher
-            or parsed_args.encryption_key_size
-            or parsed_args.encryption_control_location
-        ):
-            try:
-                _create_encryption_type(
-                    volume_client, volume_type, parsed_args
-                )
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to set encryption information for this "
-                        "volume type: %s"
-                    ),
-                    e,
-                )
-                result += 1
-
-        if result > 0:
-            raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
-            )
-
-
-class ShowVolumeType(command.ShowOne):
-    _description = _("Display volume type details")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            "volume_type",
-            metavar="<volume-type>",
-            help=_("Volume type to display (name or ID)"),
-        )
-        parser.add_argument(
-            "--encryption-type",
-            action="store_true",
-            help=_(
-                "Display encryption information of this volume type "
-                "(admin only)"
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_type = utils.find_resource(
-            volume_client.volume_types, parsed_args.volume_type
-        )
-        properties = format_columns.DictColumn(
-            volume_type._info.pop('extra_specs')
-        )
-        volume_type._info.update({'properties': properties})
-        if parsed_args.encryption_type:
-            # show encryption type information for this volume type
-            try:
-                encryption = volume_client.volume_encryption_types.get(
-                    volume_type.id
-                )
-                encryption._info.pop("volume_type_id", None)
-                volume_type._info.update(
-                    {'encryption': format_columns.DictColumn(encryption._info)}
-                )
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to display the encryption information "
-                        "of this volume type: %s"
-                    ),
-                    e,
-                )
-        volume_type._info.pop("os-volume-type-access:is_public", None)
-        return zip(*sorted(volume_type._info.items()))
-
-
-class UnsetVolumeType(command.Command):
-    _description = _("Unset volume type properties")
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'volume_type',
-            metavar='<volume-type>',
-            help=_('Volume type to modify (name or ID)'),
-        )
-        parser.add_argument(
-            '--property',
-            metavar='<key>',
-            action='append',
-            help=_(
-                'Remove a property from this volume type '
-                '(repeat option to remove multiple properties)'
-            ),
-        )
-        parser.add_argument(
-            "--encryption-type",
-            action="store_true",
-            help=_(
-                "Remove the encryption type for this volume type "
-                "(admin only)"
-            ),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_type = utils.find_resource(
-            volume_client.volume_types,
-            parsed_args.volume_type,
-        )
-
-        result = 0
-        if parsed_args.property:
-            try:
-                volume_type.unset_keys(parsed_args.property)
-            except Exception as e:
-                LOG.error(_("Failed to unset volume type property: %s"), e)
-                result += 1
-        if parsed_args.encryption_type:
-            try:
-                volume_client.volume_encryption_types.delete(volume_type)
-            except Exception as e:
-                LOG.error(
-                    _(
-                        "Failed to remove the encryption type for this "
-                        "volume type: %s"
-                    ),
-                    e,
-                )
-                result += 1
-
-        if result > 0:
-            raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
-            )
diff -pruN 7.4.0-3/openstackclient/volume/v2/consistency_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/consistency_group.py
--- 7.4.0-3/openstackclient/volume/v2/consistency_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/consistency_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -38,10 +38,7 @@ def _find_volumes(parsed_args_volumes, v
         except Exception as e:
             result += 1
             LOG.error(
-                _(
-                    "Failed to find volume with "
-                    "name or ID '%(volume)s':%(e)s"
-                )
+                _("Failed to find volume with name or ID '%(volume)s':%(e)s")
                 % {'volume': volume, 'e': e}
             )
 
@@ -76,7 +73,7 @@ class AddVolumeToConsistencyGroup(comman
         if result > 0:
             total = len(parsed_args.volumes)
             LOG.error(
-                _("%(result)s of %(total)s volumes failed " "to add.")
+                _("%(result)s of %(total)s volumes failed to add.")
                 % {'result': result, 'total': total}
             )
 
@@ -236,8 +233,7 @@ class DeleteConsistencyGroup(command.Com
         if result > 0:
             total = len(parsed_args.consistency_groups)
             msg = _(
-                "%(result)s of %(total)s consistency groups failed "
-                "to delete."
+                "%(result)s of %(total)s consistency groups failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -321,7 +317,7 @@ class RemoveVolumeFromConsistencyGroup(c
         if result > 0:
             total = len(parsed_args.volumes)
             LOG.error(
-                _("%(result)s of %(total)s volumes failed " "to remove.")
+                _("%(result)s of %(total)s volumes failed to remove.")
                 % {'result': result, 'total': total}
             )
 
diff -pruN 7.4.0-3/openstackclient/volume/v2/consistency_group_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/consistency_group_snapshot.py
--- 7.4.0-3/openstackclient/volume/v2/consistency_group_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/consistency_group_snapshot.py	2025-07-07 22:41:56.000000000 +0000
@@ -123,8 +123,7 @@ class ListConsistencyGroupSnapshot(comma
             '--all-projects',
             action="store_true",
             help=_(
-                'Show detail for all projects (admin only) '
-                '(defaults to False)'
+                'Show detail for all projects (admin only) (defaults to False)'
             ),
         )
         parser.add_argument(
diff -pruN 7.4.0-3/openstackclient/volume/v2/qos_specs.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/qos_specs.py
--- 7.4.0-3/openstackclient/volume/v2/qos_specs.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/qos_specs.py	2025-07-07 22:41:56.000000000 +0000
@@ -153,8 +153,7 @@ class DeleteQos(command.Command):
         if result > 0:
             total = len(parsed_args.qos_specs)
             msg = _(
-                "%(result)s of %(total)s QoS specifications failed"
-                " to delete."
+                "%(result)s of %(total)s QoS specifications failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
diff -pruN 7.4.0-3/openstackclient/volume/v2/service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/service.py
--- 7.4.0-3/openstackclient/volume/v2/service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/service.py	2025-07-07 22:41:56.000000000 +0000
@@ -45,33 +45,34 @@ class ListService(command.Lister):
         return parser
 
     def take_action(self, parsed_args):
-        service_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        columns: tuple[str, ...] = (
+            "binary",
+            "host",
+            "availability_zone",
+            "status",
+            "state",
+            "updated_at",
+        )
+        column_names: tuple[str, ...] = (
+            "Binary",
+            "Host",
+            "Zone",
+            "Status",
+            "State",
+            "Updated At",
+        )
 
         if parsed_args.long:
-            columns = [
-                "Binary",
-                "Host",
-                "Zone",
-                "Status",
-                "State",
-                "Updated At",
-                "Disabled Reason",
-            ]
-        else:
-            columns = [
-                "Binary",
-                "Host",
-                "Zone",
-                "Status",
-                "State",
-                "Updated At",
-            ]
+            columns += ("disabled_reason",)
+            column_names += ("Disabled Reason",)
 
-        data = service_client.services.list(
-            parsed_args.host, parsed_args.service
+        data = volume_client.services(
+            host=parsed_args.host, binary=parsed_args.service
         )
         return (
-            columns,
+            column_names,
             (
                 utils.get_item_properties(
                     s,
@@ -87,7 +88,11 @@ class SetService(command.Command):
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
-        parser.add_argument("host", metavar="<host>", help=_("Name of host"))
+        parser.add_argument(
+            "host",
+            metavar="<host>",
+            help=_("Name of host"),
+        )
         parser.add_argument(
             "service",
             metavar="<service>",
@@ -118,19 +123,17 @@ class SetService(command.Command):
             )
             raise exceptions.CommandError(msg)
 
-        service_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        service = volume_client.find_service(
+            host=parsed_args.host, service=parsed_args.service
+        )
+
         if parsed_args.enable:
-            service_client.services.enable(
-                parsed_args.host, parsed_args.service
-            )
+            service.enable(volume_client)
+
         if parsed_args.disable:
-            if parsed_args.disable_reason:
-                service_client.services.disable_log_reason(
-                    parsed_args.host,
-                    parsed_args.service,
-                    parsed_args.disable_reason,
-                )
-            else:
-                service_client.services.disable(
-                    parsed_args.host, parsed_args.service
-                )
+            service.disable(
+                volume_client,
+                reason=parsed_args.disable_reason,
+            )
diff -pruN 7.4.0-3/openstackclient/volume/v2/volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume.py
--- 7.4.0-3/openstackclient/volume/v2/volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume.py	2025-07-07 22:41:56.000000000 +0000
@@ -107,7 +107,7 @@ class CreateVolume(command.ShowOne):
             )
             raise exceptions.CommandError(msg)
 
-    def _get_parser(self, prog_name):
+    def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
         parser.add_argument(
             "name",
@@ -169,6 +169,7 @@ class CreateVolume(command.ShowOne):
             "--property",
             metavar="<key=value>",
             action=parseractions.KeyValueAction,
+            dest="properties",
             help=_(
                 "Set a property to this volume "
                 "(repeat option to set multiple properties)"
@@ -189,32 +190,36 @@ class CreateVolume(command.ShowOne):
         bootable_group.add_argument(
             "--bootable",
             action="store_true",
+            dest="bootable",
+            default=None,
             help=_("Mark volume as bootable"),
         )
         bootable_group.add_argument(
             "--non-bootable",
-            action="store_true",
+            action="store_false",
+            dest="bootable",
+            default=None,
             help=_("Mark volume as non-bootable (default)"),
         )
         readonly_group = parser.add_mutually_exclusive_group()
         readonly_group.add_argument(
             "--read-only",
             action="store_true",
+            dest="read_only",
+            default=None,
             help=_("Set volume to read-only access mode"),
         )
         readonly_group.add_argument(
             "--read-write",
-            action="store_true",
+            action="store_false",
+            dest="read_only",
+            default=None,
             help=_("Set volume to read-write access mode (default)"),
         )
-        return parser, source_group
-
-    def get_parser(self, prog_name):
-        parser, _ = self._get_parser(prog_name)
         return parser
 
     def take_action(self, parsed_args):
-        CreateVolume._check_size_arg(parsed_args)
+        self._check_size_arg(parsed_args)
         # size is validated in the above call to
         # _check_size_arg where we check that size
         # should be passed if we are not creating a
@@ -265,14 +270,14 @@ class CreateVolume(command.ShowOne):
             description=parsed_args.description,
             volume_type=parsed_args.type,
             availability_zone=parsed_args.availability_zone,
-            metadata=parsed_args.property,
+            metadata=parsed_args.properties,
             imageRef=image,
             source_volid=source_volume,
             consistencygroup_id=consistency_group,
             scheduler_hints=parsed_args.hint,
         )
 
-        if parsed_args.bootable or parsed_args.non_bootable:
+        if parsed_args.bootable is not None:
             try:
                 if utils.wait_for_status(
                     volume_client.volumes.get,
@@ -286,13 +291,13 @@ class CreateVolume(command.ShowOne):
                     )
                 else:
                     msg = _(
-                        "Volume status is not available for setting boot "
-                        "state"
+                        "Volume status is not available for setting boot state"
                     )
                     raise exceptions.CommandError(msg)
             except Exception as e:
                 LOG.error(_("Failed to set volume bootable property: %s"), e)
-        if parsed_args.read_only or parsed_args.read_write:
+
+        if parsed_args.read_only is not None:
             try:
                 if utils.wait_for_status(
                     volume_client.volumes.get,
@@ -312,10 +317,7 @@ class CreateVolume(command.ShowOne):
                     raise exceptions.CommandError(msg)
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to set volume read-only access "
-                        "mode flag: %s"
-                    ),
+                    _("Failed to set volume read-only access mode flag: %s"),
                     e,
                 )
 
@@ -356,25 +358,25 @@ class DeleteVolume(command.Command):
             "--purge",
             action="store_true",
             help=_(
-                "Remove any snapshots along with volume(s) "
-                "(defaults to False)"
+                "Remove any snapshots along with volume(s) (defaults to False)"
             ),
         )
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
         result = 0
 
-        for i in parsed_args.volumes:
+        for volume in parsed_args.volumes:
             try:
-                volume_obj = utils.find_resource(volume_client.volumes, i)
-                if parsed_args.force:
-                    volume_client.volumes.force_delete(volume_obj.id)
-                else:
-                    volume_client.volumes.delete(
-                        volume_obj.id, cascade=parsed_args.purge
-                    )
+                volume_obj = volume_client.find_volume(
+                    volume, ignore_missing=False
+                )
+                volume_client.delete_volume(
+                    volume_obj.id,
+                    force=parsed_args.force,
+                    cascade=parsed_args.purge,
+                )
             except Exception as e:
                 result += 1
                 LOG.error(
@@ -382,12 +384,12 @@ class DeleteVolume(command.Command):
                         "Failed to delete volume with "
                         "name or ID '%(volume)s': %(e)s"
                     ),
-                    {'volume': i, 'e': e},
+                    {'volume': volume, 'e': e},
                 )
 
         if result > 0:
             total = len(parsed_args.volumes)
-            msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s volumes failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -508,7 +510,7 @@ class ListVolume(command.Lister):
         server_cache = {}
         if do_server_list:
             try:
-                compute_client = self.app.client_manager.sdk_connection.compute
+                compute_client = self.app.client_manager.compute
                 for s in compute_client.servers():
                     server_cache[s.id] = s
             except sdk_exceptions.SDKException:  # noqa: S110
@@ -627,6 +629,7 @@ class SetVolume(command.Command):
             '--property',
             metavar='<key=value>',
             action=parseractions.KeyValueAction,
+            dest="properties",
             help=_(
                 'Set a property on this volume '
                 '(repeat option to set multiple properties)'
@@ -636,6 +639,7 @@ class SetVolume(command.Command):
             '--image-property',
             metavar='<key=value>',
             action=parseractions.KeyValueAction,
+            dest="image_properties",
             help=_(
                 'Set an image property on this volume '
                 '(repeat option to set multiple image properties)'
@@ -712,22 +716,30 @@ class SetVolume(command.Command):
         bootable_group.add_argument(
             "--bootable",
             action="store_true",
+            dest="bootable",
+            default=None,
             help=_("Mark volume as bootable"),
         )
         bootable_group.add_argument(
             "--non-bootable",
-            action="store_true",
+            action="store_false",
+            dest="bootable",
+            default=None,
             help=_("Mark volume as non-bootable"),
         )
         readonly_group = parser.add_mutually_exclusive_group()
         readonly_group.add_argument(
             "--read-only",
             action="store_true",
+            dest="read_only",
+            default=None,
             help=_("Set volume to read-only access mode"),
         )
         readonly_group.add_argument(
             "--read-write",
-            action="store_true",
+            action="store_false",
+            dest="read_only",
+            default=None,
             help=_("Set volume to read-write access mode"),
         )
         return parser
@@ -776,28 +788,31 @@ class SetVolume(command.Command):
                 LOG.error(_("Failed to clean volume properties: %s"), e)
                 result += 1
 
-        if parsed_args.property:
+        if parsed_args.properties:
             try:
                 volume_client.volumes.set_metadata(
-                    volume.id, parsed_args.property
+                    volume.id, parsed_args.properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to set volume property: %s"), e)
+                LOG.error(_("Failed to set volume properties: %s"), e)
                 result += 1
-        if parsed_args.image_property:
+
+        if parsed_args.image_properties:
             try:
                 volume_client.volumes.set_image_metadata(
-                    volume.id, parsed_args.image_property
+                    volume.id, parsed_args.image_properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to set image property: %s"), e)
+                LOG.error(_("Failed to set image properties: %s"), e)
                 result += 1
+
         if parsed_args.state:
             try:
                 volume_client.volumes.reset_state(volume.id, parsed_args.state)
             except Exception as e:
                 LOG.error(_("Failed to set volume state: %s"), e)
                 result += 1
+
         if parsed_args.attached:
             try:
                 volume_client.volumes.reset_state(
@@ -806,6 +821,7 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume attach-status: %s"), e)
                 result += 1
+
         if parsed_args.detached:
             try:
                 volume_client.volumes.reset_state(
@@ -814,7 +830,8 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume attach-status: %s"), e)
                 result += 1
-        if parsed_args.bootable or parsed_args.non_bootable:
+
+        if parsed_args.bootable is not None:
             try:
                 volume_client.volumes.set_bootable(
                     volume.id, parsed_args.bootable
@@ -822,20 +839,19 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume bootable property: %s"), e)
                 result += 1
-        if parsed_args.read_only or parsed_args.read_write:
+
+        if parsed_args.read_only is not None:
             try:
                 volume_client.volumes.update_readonly_flag(
                     volume.id, parsed_args.read_only
                 )
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to set volume read-only access "
-                        "mode flag: %s"
-                    ),
+                    _("Failed to set volume read-only access mode flag: %s"),
                     e,
                 )
                 result += 1
+
         policy = parsed_args.migration_policy or parsed_args.retype_policy
         if parsed_args.type:
             # get the migration policy
@@ -885,7 +901,7 @@ class SetVolume(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("One or more of the " "set operations failed")
+                _("One or more of the set operations failed")
             )
 
 
@@ -936,6 +952,7 @@ class UnsetVolume(command.Command):
             '--property',
             metavar='<key>',
             action='append',
+            dest='properties',
             help=_(
                 'Remove a property from volume '
                 '(repeat option to remove multiple properties)'
@@ -945,6 +962,7 @@ class UnsetVolume(command.Command):
             '--image-property',
             metavar='<key>',
             action='append',
+            dest='image_properties',
             help=_(
                 'Remove an image property from volume '
                 '(repeat option to remove multiple image properties)'
@@ -957,25 +975,25 @@ class UnsetVolume(command.Command):
         volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
 
         result = 0
-        if parsed_args.property:
+        if parsed_args.properties:
             try:
                 volume_client.volumes.delete_metadata(
-                    volume.id, parsed_args.property
+                    volume.id, parsed_args.properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to unset volume property: %s"), e)
+                LOG.error(_("Failed to unset volume properties: %s"), e)
                 result += 1
 
-        if parsed_args.image_property:
+        if parsed_args.image_properties:
             try:
                 volume_client.volumes.delete_image_metadata(
-                    volume.id, parsed_args.image_property
+                    volume.id, parsed_args.image_properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to unset image property: %s"), e)
+                LOG.error(_("Failed to unset image properties: %s"), e)
                 result += 1
 
         if result > 0:
             raise exceptions.CommandError(
-                _("One or more of the " "unset operations failed")
+                _("One or more of the unset operations failed")
             )
diff -pruN 7.4.0-3/openstackclient/volume/v2/volume_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_backup.py
--- 7.4.0-3/openstackclient/volume/v2/volume_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_backup.py	2025-07-07 22:41:56.000000000 +0000
@@ -118,7 +118,7 @@ class CreateVolumeBackup(command.ShowOne
                 ignore_missing=False,
             ).id
 
-        columns = (
+        columns: tuple[str, ...] = (
             "id",
             "name",
             "volume_id",
@@ -240,7 +240,7 @@ class ListVolumeBackup(command.Lister):
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.sdk_connection.volume
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             'description',
@@ -249,7 +249,7 @@ class ListVolumeBackup(command.Lister):
             'is_incremental',
             'created_at',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Name',
             'Description',
@@ -345,8 +345,7 @@ class RestoreVolumeBackup(command.ShowOn
             "--force",
             action="store_true",
             help=_(
-                "Restore the backup to an existing volume "
-                "(default to False)"
+                "Restore the backup to an existing volume (default to False)"
             ),
         )
         return parser
@@ -359,7 +358,7 @@ class RestoreVolumeBackup(command.ShowOn
             ignore_missing=False,
         )
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'volume_id',
             'volume_name',
@@ -418,13 +417,19 @@ class SetVolumeBackup(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        backup = utils.find_resource(volume_client.backups, parsed_args.backup)
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        backup = volume_client.find_backup(
+            parsed_args.backup,
+            ignore_missing=False,
+        )
 
         result = 0
         if parsed_args.state:
             try:
-                volume_client.backups.reset_state(backup.id, parsed_args.state)
+                volume_client.reset_backup_status(
+                    backup, status=parsed_args.state
+                )
             except Exception as e:
                 LOG.error(_("Failed to set backup state: %s"), e)
                 result += 1
@@ -449,7 +454,7 @@ class ShowVolumeBackup(command.ShowOne):
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.sdk_connection.volume
         backup = volume_client.find_backup(parsed_args.backup)
-        columns = (
+        columns: tuple[str, ...] = (
             "availability_zone",
             "container",
             "created_at",
diff -pruN 7.4.0-3/openstackclient/volume/v2/volume_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_snapshot.py
--- 7.4.0-3/openstackclient/volume/v2/volume_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_snapshot.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,11 +14,12 @@
 
 """Volume v2 snapshot action implementations"""
 
-import copy
 import functools
 import logging
+import typing as ty
 
 from cliff import columns as cliff_columns
+from openstack.block_storage.v2 import snapshot as _snapshot
 from osc_lib.cli import format_columns
 from osc_lib.cli import parseractions
 from osc_lib.command import command
@@ -60,6 +61,42 @@ class VolumeIdColumn(cliff_columns.Forma
         return volume
 
 
+def _format_snapshot(snapshot: _snapshot.Snapshot) -> dict[str, ty.Any]:
+    # Some columns returned by openstacksdk should not be shown because they're
+    # either irrelevant or duplicates
+    ignored_columns = {
+        # computed columns
+        'location',
+        # create-only columns
+        'consumes_quota',
+        'force',
+        'group_snapshot_id',
+        # ignored columns
+        'os-extended-snapshot-attributes:progress',
+        'os-extended-snapshot-attributes:project_id',
+        'updated_at',
+        'user_id',
+        # unnecessary columns
+        'links',
+    }
+
+    info = snapshot.to_dict(original_names=True)
+    data = {}
+    for key, value in info.items():
+        if key in ignored_columns:
+            continue
+
+        data[key] = value
+
+    data.update(
+        {
+            'properties': format_columns.DictColumn(data.pop('metadata')),
+        }
+    )
+
+    return data
+
+
 class CreateVolumeSnapshot(command.ShowOne):
     _description = _("Create new volume snapshot")
 
@@ -74,8 +111,7 @@ class CreateVolumeSnapshot(command.ShowO
             "--volume",
             metavar="<volume>",
             help=_(
-                "Volume to snapshot (name or ID) "
-                "(default is <snapshot-name>)"
+                "Volume to snapshot (name or ID) (default is <snapshot-name>)"
             ),
         )
         parser.add_argument(
@@ -88,14 +124,14 @@ class CreateVolumeSnapshot(command.ShowO
             action="store_true",
             default=False,
             help=_(
-                "Create a snapshot attached to an instance. "
-                "Default is False"
+                "Create a snapshot attached to an instance. Default is False"
             ),
         )
         parser.add_argument(
             "--property",
             metavar="<key=value>",
             action=parseractions.KeyValueAction,
+            dest="properties",
             help=_(
                 "Set a property to this snapshot "
                 "(repeat option to set multiple properties)"
@@ -115,11 +151,13 @@ class CreateVolumeSnapshot(command.ShowO
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
+
         volume = parsed_args.volume
         if not parsed_args.volume:
             volume = parsed_args.snapshot_name
-        volume_id = utils.find_resource(volume_client.volumes, volume).id
+        volume_id = volume_client.find_volume(volume, ignore_missing=False).id
+
         if parsed_args.remote_source:
             # Create a new snapshot from an existing remote snapshot source
             if parsed_args.force:
@@ -129,30 +167,26 @@ class CreateVolumeSnapshot(command.ShowO
                     "volume snapshot"
                 )
                 LOG.warning(msg)
-            snapshot = volume_client.volume_snapshots.manage(
+
+            snapshot = volume_client.manage_snapshot(
                 volume_id=volume_id,
                 ref=parsed_args.remote_source,
                 name=parsed_args.snapshot_name,
                 description=parsed_args.description,
-                metadata=parsed_args.property,
+                metadata=parsed_args.properties,
             )
         else:
             # create a new snapshot from scratch
-            snapshot = volume_client.volume_snapshots.create(
-                volume_id,
+            snapshot = volume_client.create_snapshot(
+                volume_id=volume_id,
                 force=parsed_args.force,
                 name=parsed_args.snapshot_name,
                 description=parsed_args.description,
-                metadata=parsed_args.property,
+                metadata=parsed_args.properties,
             )
-        snapshot._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    snapshot._info.pop('metadata')
-                )
-            }
-        )
-        return zip(*sorted(snapshot._info.items()))
+
+        data = _format_snapshot(snapshot)
+        return zip(*sorted(data.items()))
 
 
 class DeleteVolumeSnapshot(command.Command):
@@ -177,16 +211,16 @@ class DeleteVolumeSnapshot(command.Comma
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
         result = 0
 
-        for i in parsed_args.snapshots:
+        for snapshot in parsed_args.snapshots:
             try:
-                snapshot_id = utils.find_resource(
-                    volume_client.volume_snapshots, i
+                snapshot_id = volume_client.find_snapshot(
+                    snapshot, ignore_missing=False
                 ).id
-                volume_client.volume_snapshots.delete(
-                    snapshot_id, parsed_args.force
+                volume_client.delete_snapshot(
+                    snapshot_id, force=parsed_args.force
                 )
             except Exception as e:
                 result += 1
@@ -195,14 +229,15 @@ class DeleteVolumeSnapshot(command.Comma
                         "Failed to delete snapshot with "
                         "name or ID '%(snapshot)s': %(e)s"
                     )
-                    % {'snapshot': i, 'e': e}
+                    % {'snapshot': snapshot, 'e': e}
                 )
 
         if result > 0:
             total = len(parsed_args.snapshots)
-            msg = _(
-                "%(result)s of %(total)s snapshots failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s snapshots failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
 
 
@@ -261,31 +296,39 @@ class ListVolumeSnapshot(command.Lister)
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
         identity_client = self.app.client_manager.identity
 
+        columns: tuple[str, ...] = (
+            'id',
+            'name',
+            'description',
+            'status',
+            'size',
+        )
+        column_headers: tuple[str, ...] = (
+            'ID',
+            'Name',
+            'Description',
+            'Status',
+            'Size',
+        )
         if parsed_args.long:
-            columns = [
-                'ID',
-                'Name',
-                'Description',
-                'Status',
-                'Size',
+            columns += (
+                'created_at',
+                'volume_id',
+                'metadata',
+            )
+            column_headers += (
                 'Created At',
-                'Volume ID',
-                'Metadata',
-            ]
-            column_headers = copy.deepcopy(columns)
-            column_headers[6] = 'Volume'
-            column_headers[7] = 'Properties'
-        else:
-            columns = ['ID', 'Name', 'Description', 'Status', 'Size']
-            column_headers = copy.deepcopy(columns)
+                'Volume',
+                'Properties',
+            )
 
         # Cache the volume list
         volume_cache = {}
         try:
-            for s in volume_client.volumes.list():
+            for s in volume_client.volumes():
                 volume_cache[s.id] = s
         except Exception:  # noqa: S110
             # Just forget it if there's any trouble
@@ -296,8 +339,8 @@ class ListVolumeSnapshot(command.Lister)
 
         volume_id = None
         if parsed_args.volume:
-            volume_id = utils.find_resource(
-                volume_client.volumes, parsed_args.volume
+            volume_id = volume_client.find_volume(
+                parsed_args.volume, ignore_missing=False
             ).id
 
         project_id = None
@@ -313,18 +356,14 @@ class ListVolumeSnapshot(command.Lister)
             True if parsed_args.project else parsed_args.all_projects
         )
 
-        search_opts = {
-            'all_tenants': all_projects,
-            'project_id': project_id,
-            'name': parsed_args.name,
-            'status': parsed_args.status,
-            'volume_id': volume_id,
-        }
-
-        data = volume_client.volume_snapshots.list(
-            search_opts=search_opts,
+        data = volume_client.snapshots(
             marker=parsed_args.marker,
             limit=parsed_args.limit,
+            all_projects=all_projects,
+            project_id=project_id,
+            name=parsed_args.name,
+            status=parsed_args.status,
+            volume_id=volume_id,
         )
         return (
             column_headers,
@@ -333,8 +372,8 @@ class ListVolumeSnapshot(command.Lister)
                     s,
                     columns,
                     formatters={
-                        'Metadata': format_columns.DictColumn,
-                        'Volume ID': _VolumeIdColumn,
+                        'metadata': format_columns.DictColumn,
+                        'volume_id': _VolumeIdColumn,
                     },
                 )
                 for s in data
@@ -375,6 +414,7 @@ class SetVolumeSnapshot(command.Command)
             '--property',
             metavar='<key=value>',
             action=parseractions.KeyValueAction,
+            dest='properties',
             help=_(
                 'Property to add/change for this snapshot '
                 '(repeat option to set multiple properties)'
@@ -401,27 +441,26 @@ class SetVolumeSnapshot(command.Command)
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        snapshot = utils.find_resource(
-            volume_client.volume_snapshots, parsed_args.snapshot
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        snapshot = volume_client.find_snapshot(
+            parsed_args.snapshot, ignore_missing=False
         )
 
         result = 0
         if parsed_args.no_property:
             try:
-                key_list = snapshot.metadata.keys()
-                volume_client.volume_snapshots.delete_metadata(
-                    snapshot.id,
-                    list(key_list),
+                volume_client.delete_snapshot_metadata(
+                    snapshot.id, keys=list(snapshot.metadata)
                 )
             except Exception as e:
                 LOG.error(_("Failed to clean snapshot properties: %s"), e)
                 result += 1
 
-        if parsed_args.property:
+        if parsed_args.properties:
             try:
-                volume_client.volume_snapshots.set_metadata(
-                    snapshot.id, parsed_args.property
+                volume_client.set_snapshot_metadata(
+                    snapshot.id, **parsed_args.properties
                 )
             except Exception as e:
                 LOG.error(_("Failed to set snapshot property: %s"), e)
@@ -429,7 +468,7 @@ class SetVolumeSnapshot(command.Command)
 
         if parsed_args.state:
             try:
-                volume_client.volume_snapshots.reset_state(
+                volume_client.reset_snapshot_status(
                     snapshot.id, parsed_args.state
                 )
             except Exception as e:
@@ -443,17 +482,17 @@ class SetVolumeSnapshot(command.Command)
             kwargs['description'] = parsed_args.description
         if kwargs:
             try:
-                volume_client.volume_snapshots.update(snapshot.id, **kwargs)
+                volume_client.update_snapshot(snapshot.id, **kwargs)
             except Exception as e:
                 LOG.error(
-                    _("Failed to update snapshot name " "or description: %s"),
+                    _("Failed to update snapshot name or description: %s"),
                     e,
                 )
                 result += 1
 
         if result > 0:
             raise exceptions.CommandError(
-                _("One or more of the " "set operations failed")
+                _("One or more of the set operations failed")
             )
 
 
@@ -470,18 +509,14 @@ class ShowVolumeSnapshot(command.ShowOne
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        snapshot = utils.find_resource(
-            volume_client.volume_snapshots, parsed_args.snapshot
-        )
-        snapshot._info.update(
-            {
-                'properties': format_columns.DictColumn(
-                    snapshot._info.pop('metadata')
-                )
-            }
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        snapshot = volume_client.find_snapshot(
+            parsed_args.snapshot, ignore_missing=False
         )
-        return zip(*sorted(snapshot._info.items()))
+
+        data = _format_snapshot(snapshot)
+        return zip(*sorted(data.items()))
 
 
 class UnsetVolumeSnapshot(command.Command):
@@ -499,6 +534,7 @@ class UnsetVolumeSnapshot(command.Comman
             metavar='<key>',
             action='append',
             default=[],
+            dest='properties',
             help=_(
                 'Property to remove from snapshot '
                 '(repeat option to remove multiple properties)'
@@ -507,13 +543,13 @@ class UnsetVolumeSnapshot(command.Comman
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        snapshot = utils.find_resource(
-            volume_client.volume_snapshots, parsed_args.snapshot
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        snapshot = volume_client.find_snapshot(
+            parsed_args.snapshot, ignore_missing=False
         )
 
-        if parsed_args.property:
-            volume_client.volume_snapshots.delete_metadata(
-                snapshot.id,
-                parsed_args.property,
+        if parsed_args.properties:
+            volume_client.delete_snapshot_metadata(
+                snapshot.id, keys=parsed_args.properties
             )
diff -pruN 7.4.0-3/openstackclient/volume/v2/volume_transfer_request.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_transfer_request.py
--- 7.4.0-3/openstackclient/volume/v2/volume_transfer_request.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_transfer_request.py	2025-07-07 22:41:56.000000000 +0000
@@ -85,8 +85,6 @@ class CreateTransferRequest(command.Show
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.volume
 
-        kwargs = {}
-
         volume_id = utils.find_resource(
             volume_client.volumes,
             parsed_args.volume,
@@ -94,7 +92,6 @@ class CreateTransferRequest(command.Show
         volume_transfer_request = volume_client.transfers.create(
             volume_id,
             parsed_args.name,
-            **kwargs,
         )
         volume_transfer_request._info.pop("links", None)
 
diff -pruN 7.4.0-3/openstackclient/volume/v2/volume_type.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_type.py
--- 7.4.0-3/openstackclient/volume/v2/volume_type.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v2/volume_type.py	2025-07-07 22:41:56.000000000 +0000
@@ -272,8 +272,7 @@ class CreateVolumeType(command.ShowOne):
                 )
             except Exception as e:
                 msg = _(
-                    "Failed to add project %(project)s access to "
-                    "type: %(e)s"
+                    "Failed to add project %(project)s access to type: %(e)s"
                 )
                 LOG.error(msg % {'project': parsed_args.project, 'e': e})
 
@@ -363,7 +362,7 @@ class DeleteVolumeType(command.Command):
         if result > 0:
             total = len(parsed_args.volume_types)
             msg = _(
-                "%(result)s of %(total)s volume types failed " "to delete."
+                "%(result)s of %(total)s volume types failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -553,8 +552,7 @@ class SetVolumeType(command.Command):
             '--project',
             metavar='<project>',
             help=_(
-                'Set volume type access to project (name or ID) '
-                '(admin only)'
+                'Set volume type access to project (name or ID) (admin only)'
             ),
         )
         public_group = parser.add_mutually_exclusive_group()
@@ -646,17 +644,12 @@ class SetVolumeType(command.Command):
                 volume_client.volume_types.update(volume_type.id, **kwargs)
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to update volume type name or"
-                        " description: %s"
-                    ),
+                    _("Failed to update volume type name or description: %s"),
                     e,
                 )
                 result += 1
 
-        properties = {}
-
-        properties = {}
+        properties: dict[str, str] = {}
         if parsed_args.properties:
             properties.update(parsed_args.properties)
         if parsed_args.multiattach:
@@ -690,7 +683,7 @@ class SetVolumeType(command.Command):
                 )
             except Exception as e:
                 LOG.error(
-                    _("Failed to set volume type access to " "project: %s"), e
+                    _("Failed to set volume type access to project: %s"), e
                 )
                 result += 1
 
@@ -714,7 +707,7 @@ class SetVolumeType(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
+                _("Command Failed: One or more of the operations failed")
             )
 
 
@@ -822,8 +815,7 @@ class UnsetVolumeType(command.Command):
             "--encryption-type",
             action="store_true",
             help=_(
-                "Remove the encryption type for this volume type "
-                "(admin only)"
+                "Remove the encryption type for this volume type (admin only)"
             ),
         )
         return parser
@@ -859,10 +851,7 @@ class UnsetVolumeType(command.Command):
                 )
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to remove volume type access from "
-                        "project: %s"
-                    ),
+                    _("Failed to remove volume type access from project: %s"),
                     e,
                 )
                 result += 1
@@ -881,5 +870,5 @@ class UnsetVolumeType(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
+                _("Command Failed: One or more of the operations failed")
             )
diff -pruN 7.4.0-3/openstackclient/volume/v3/block_storage_cluster.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/block_storage_cluster.py
--- 7.4.0-3/openstackclient/volume/v3/block_storage_cluster.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/block_storage_cluster.py	2025-07-07 22:41:56.000000000 +0000
@@ -19,13 +19,13 @@ from openstackclient.i18n import _
 
 
 def _format_cluster(cluster, detailed=False):
-    columns = (
+    columns: tuple[str, ...] = (
         'name',
         'binary',
         'state',
         'status',
     )
-    column_headers = (
+    column_headers: tuple[str, ...] = (
         'Name',
         'Binary',
         'State',
@@ -147,7 +147,7 @@ class ListBlockStorageCluster(command.Li
             )
             raise exceptions.CommandError(msg)
 
-        columns = ('Name', 'Binary', 'State', 'Status')
+        columns: tuple[str, ...] = ('Name', 'Binary', 'State', 'Status')
         if parsed_args.long:
             columns += (
                 'Num Hosts',
diff -pruN 7.4.0-3/openstackclient/volume/v3/block_storage_log_level.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/block_storage_log_level.py
--- 7.4.0-3/openstackclient/volume/v3/block_storage_log_level.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/block_storage_log_level.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,10 +14,9 @@
 
 """Block Storage Service action implementations"""
 
-from cinderclient import api_versions
+from openstack import utils as sdk_utils
 from osc_lib.command import command
 from osc_lib import exceptions
-from osc_lib import utils
 
 from openstackclient.i18n import _
 
@@ -33,7 +32,7 @@ class BlockStorageLogLevelList(command.L
         parser.add_argument(
             "--host",
             metavar="<host>",
-            default="",
+            default=None,
             help=_(
                 "List block storage service log level of specified host "
                 "(name only)"
@@ -42,9 +41,9 @@ class BlockStorageLogLevelList(command.L
         parser.add_argument(
             "--service",
             metavar="<service>",
-            default="",
+            default=None,
             choices=(
-                '',
+                None,
                 '*',
                 'cinder-api',
                 'cinder-volume',
@@ -59,13 +58,13 @@ class BlockStorageLogLevelList(command.L
         parser.add_argument(
             "--log-prefix",
             metavar="<log-prefix>",
-            default="",
+            default=None,
             help="Prefix for the log, e.g. 'sqlalchemy'",
         )
         return parser
 
     def take_action(self, parsed_args):
-        service_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
         columns = [
             "Binary",
             "Host",
@@ -73,29 +72,24 @@ class BlockStorageLogLevelList(command.L
             "Level",
         ]
 
-        if service_client.api_version < api_versions.APIVersion('3.32'):
+        if not sdk_utils.supports_microversion(volume_client, '3.32'):
             msg = _(
                 "--os-volume-api-version 3.32 or greater is required to "
                 "support the 'block storage log level list' command"
             )
             raise exceptions.CommandError(msg)
 
-        data = service_client.services.get_log_levels(
+        data = []
+        for entry in volume_client.get_service_log_levels(
             binary=parsed_args.service,
             server=parsed_args.host,
             prefix=parsed_args.log_prefix,
-        )
+        ):
+            entry_levels = sorted(entry.levels.items(), key=lambda x: x[0])
+            for prefix, level in entry_levels:
+                data.append((entry.binary, entry.host, prefix, level))
 
-        return (
-            columns,
-            (
-                utils.get_item_properties(
-                    s,
-                    columns,
-                )
-                for s in data
-            ),
-        )
+        return (columns, data)
 
 
 class BlockStorageLogLevelSet(command.Command):
@@ -111,12 +105,12 @@ class BlockStorageLogLevelSet(command.Co
             metavar="<log-level>",
             choices=('INFO', 'WARNING', 'ERROR', 'DEBUG'),
             type=str.upper,
-            help=_("Desired log level."),
+            help=_("Desired log level"),
         )
         parser.add_argument(
             "--host",
             metavar="<host>",
-            default="",
+            default=None,
             help=_(
                 "Set block storage service log level of specified host "
                 "(name only)"
@@ -125,9 +119,9 @@ class BlockStorageLogLevelSet(command.Co
         parser.add_argument(
             "--service",
             metavar="<service>",
-            default="",
+            default=None,
             choices=(
-                '',
+                None,
                 '*',
                 'cinder-api',
                 'cinder-volume',
@@ -142,22 +136,22 @@ class BlockStorageLogLevelSet(command.Co
         parser.add_argument(
             "--log-prefix",
             metavar="<log-prefix>",
-            default="",
+            default=None,
             help="Prefix for the log, e.g. 'sqlalchemy'",
         )
         return parser
 
     def take_action(self, parsed_args):
-        service_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
 
-        if service_client.api_version < api_versions.APIVersion('3.32'):
+        if not sdk_utils.supports_microversion(volume_client, '3.32'):
             msg = _(
                 "--os-volume-api-version 3.32 or greater is required to "
                 "support the 'block storage log level set' command"
             )
             raise exceptions.CommandError(msg)
 
-        service_client.services.set_log_levels(
+        volume_client.set_service_log_levels(
             level=parsed_args.level,
             binary=parsed_args.service,
             server=parsed_args.host,
diff -pruN 7.4.0-3/openstackclient/volume/v3/block_storage_manage.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/block_storage_manage.py
--- 7.4.0-3/openstackclient/volume/v3/block_storage_manage.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/block_storage_manage.py	2025-07-07 22:41:56.000000000 +0000
@@ -317,9 +317,7 @@ class BlockStorageManageSnapshots(comman
                 # if the user requested e.g. '--detailed false' then they
                 # should simply stop requesting this since the default has
                 # changed
-                msg = _(
-                    "The --detailed option has been deprecated. " "Unset it."
-                )
+                msg = _("The --detailed option has been deprecated. Unset it.")
                 self.log.warning(msg)
 
         columns = [
diff -pruN 7.4.0-3/openstackclient/volume/v3/service.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/service.py
--- 7.4.0-3/openstackclient/volume/v3/service.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/service.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,37 +14,72 @@
 
 """Service action implementations"""
 
-from cinderclient import api_versions
+from openstack import utils as sdk_utils
+from osc_lib.command import command
+from osc_lib import exceptions
 from osc_lib import utils
 
-from openstackclient.volume.v2 import service as service_v2
+from openstackclient.i18n import _
 
 
-class ListService(service_v2.ListService):
+class ListService(command.Lister):
+    _description = _("List service command")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "--host",
+            metavar="<host>",
+            help=_("List services on specified host (name only)"),
+        )
+        parser.add_argument(
+            "--service",
+            metavar="<service>",
+            help=_("List only specified service (name only)"),
+        )
+        parser.add_argument(
+            "--long",
+            action="store_true",
+            default=False,
+            help=_("List additional fields in output"),
+        )
+        return parser
+
     def take_action(self, parsed_args):
-        service_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
 
-        columns = [
+        columns: tuple[str, ...] = (
+            "binary",
+            "host",
+            "availability_zone",
+            "status",
+            "state",
+            "updated_at",
+        )
+        column_names: tuple[str, ...] = (
             "Binary",
             "Host",
             "Zone",
             "Status",
             "State",
             "Updated At",
-        ]
+        )
 
-        if service_client.api_version >= api_versions.APIVersion('3.7'):
-            columns.append("Cluster")
-        if service_client.api_version >= api_versions.APIVersion('3.49'):
-            columns.append("Backend State")
+        if sdk_utils.supports_microversion(volume_client, '3.7'):
+            columns += ("cluster",)
+            column_names += ("Cluster",)
+        if sdk_utils.supports_microversion(volume_client, '3.49'):
+            columns += ("backend_state",)
+            column_names += ("Backend State",)
         if parsed_args.long:
-            columns.append("Disabled Reason")
+            columns += ("disabled_reason",)
+            column_names += ("Disabled Reason",)
 
-        data = service_client.services.list(
-            parsed_args.host, parsed_args.service
+        data = volume_client.services(
+            host=parsed_args.host, binary=parsed_args.service
         )
         return (
-            columns,
+            column_names,
             (
                 utils.get_item_properties(
                     s,
@@ -53,3 +88,59 @@ class ListService(service_v2.ListService
                 for s in data
             ),
         )
+
+
+class SetService(command.Command):
+    _description = _("Set volume service properties")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "host",
+            metavar="<host>",
+            help=_("Name of host"),
+        )
+        parser.add_argument(
+            "service",
+            metavar="<service>",
+            help=_("Name of service (Binary name)"),
+        )
+        enabled_group = parser.add_mutually_exclusive_group()
+        enabled_group.add_argument(
+            "--enable", action="store_true", help=_("Enable volume service")
+        )
+        enabled_group.add_argument(
+            "--disable", action="store_true", help=_("Disable volume service")
+        )
+        parser.add_argument(
+            "--disable-reason",
+            metavar="<reason>",
+            help=_(
+                "Reason for disabling the service "
+                "(should be used with --disable option)"
+            ),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        if parsed_args.disable_reason and not parsed_args.disable:
+            msg = _(
+                "Cannot specify option --disable-reason without "
+                "--disable specified."
+            )
+            raise exceptions.CommandError(msg)
+
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        service = volume_client.find_service(
+            host=parsed_args.host, service=parsed_args.service
+        )
+
+        if parsed_args.enable:
+            service.enable(volume_client)
+
+        if parsed_args.disable:
+            service.disable(
+                volume_client,
+                reason=parsed_args.disable_reason,
+            )
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume.py
--- 7.4.0-3/openstackclient/volume/v3/volume.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume.py	2025-07-07 22:41:56.000000000 +0000
@@ -31,7 +31,6 @@ from osc_lib import utils
 from openstackclient.common import pagination
 from openstackclient.i18n import _
 from openstackclient.identity import common as identity_common
-from openstackclient.volume.v2 import volume as volume_v2
 
 
 LOG = logging.getLogger(__name__)
@@ -91,7 +90,7 @@ class AttachmentsColumn(cliff_columns.Fo
         return msg
 
 
-class CreateVolume(volume_v2.CreateVolume):
+class CreateVolume(command.ShowOne):
     _description = _("Create new volume")
 
     @staticmethod
@@ -117,8 +116,48 @@ class CreateVolume(volume_v2.CreateVolum
             raise exceptions.CommandError(msg)
 
     def get_parser(self, prog_name):
-        parser, source_group = self._get_parser(prog_name)
-
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "name",
+            metavar="<name>",
+            nargs="?",
+            help=_("Volume name"),
+        )
+        parser.add_argument(
+            "--size",
+            metavar="<size>",
+            type=int,
+            help=_(
+                "Volume size in GB (required unless --snapshot or "
+                "--source specified)"
+            ),
+        )
+        parser.add_argument(
+            "--type",
+            metavar="<volume-type>",
+            help=_("Set the type of volume"),
+        )
+        source_group = parser.add_mutually_exclusive_group()
+        source_group.add_argument(
+            "--image",
+            metavar="<image>",
+            help=_("Use <image> as source of volume (name or ID)"),
+        )
+        source_group.add_argument(
+            "--snapshot",
+            metavar="<snapshot>",
+            help=_("Use <snapshot> as source of volume (name or ID)"),
+        )
+        source_group.add_argument(
+            "--source",
+            metavar="<volume>",
+            help=_("Volume to clone (name or ID)"),
+        )
+        source_group.add_argument(
+            "--source-replicated",
+            metavar="<replicated-volume>",
+            help=argparse.SUPPRESS,
+        )
         source_group.add_argument(
             "--backup",
             metavar="<backup>",
@@ -139,6 +178,72 @@ class CreateVolume(volume_v2.CreateVolum
             ),
         )
         parser.add_argument(
+            "--description",
+            metavar="<description>",
+            help=_("Volume description"),
+        )
+        parser.add_argument(
+            "--availability-zone",
+            metavar="<availability-zone>",
+            help=_("Create volume in <availability-zone>"),
+        )
+        parser.add_argument(
+            "--consistency-group",
+            metavar="consistency-group>",
+            help=_("Consistency group where the new volume belongs to"),
+        )
+        parser.add_argument(
+            "--property",
+            metavar="<key=value>",
+            action=parseractions.KeyValueAction,
+            dest="properties",
+            help=_(
+                "Set a property to this volume "
+                "(repeat option to set multiple properties)"
+            ),
+        )
+        parser.add_argument(
+            "--hint",
+            metavar="<key=value>",
+            action=KeyValueHintAction,
+            help=_(
+                "Arbitrary scheduler hint key-value pairs to help creating "
+                "a volume. Repeat the option to set multiple hints. "
+                "'same_host' and 'different_host' get values appended when "
+                "repeated, all other keys take the last given value"
+            ),
+        )
+        bootable_group = parser.add_mutually_exclusive_group()
+        bootable_group.add_argument(
+            "--bootable",
+            action="store_true",
+            dest="bootable",
+            default=None,
+            help=_("Mark volume as bootable"),
+        )
+        bootable_group.add_argument(
+            "--non-bootable",
+            action="store_false",
+            dest="bootable",
+            default=None,
+            help=_("Mark volume as non-bootable (default)"),
+        )
+        readonly_group = parser.add_mutually_exclusive_group()
+        readonly_group.add_argument(
+            "--read-only",
+            action="store_true",
+            dest="read_only",
+            default=None,
+            help=_("Set volume to read-only access mode"),
+        )
+        readonly_group.add_argument(
+            "--read-write",
+            action="store_false",
+            dest="read_only",
+            default=None,
+            help=_("Set volume to read-write access mode (default)"),
+        )
+        parser.add_argument(
             "--host",
             metavar="<host>",
             help=_(
@@ -160,7 +265,7 @@ class CreateVolume(volume_v2.CreateVolum
         return parser
 
     def take_action(self, parsed_args):
-        CreateVolume._check_size_arg(parsed_args)
+        self._check_size_arg(parsed_args)
         # size is validated in the above call to
         # _check_size_arg where we check that size
         # should be passed if we are not creating a
@@ -194,8 +299,7 @@ class CreateVolume(volume_v2.CreateVolum
                 parsed_args.size
                 or parsed_args.consistency_group
                 or parsed_args.hint
-                or parsed_args.read_only
-                or parsed_args.read_write
+                or parsed_args.read_only is not None
             ):
                 msg = _(
                     "The --size, --consistency-group, --hint, --read-only "
@@ -232,10 +336,24 @@ class CreateVolume(volume_v2.CreateVolum
                 description=parsed_args.description,
                 volume_type=parsed_args.type,
                 availability_zone=parsed_args.availability_zone,
-                metadata=parsed_args.property,
+                metadata=parsed_args.properties,
                 bootable=parsed_args.bootable,
             )
-            return zip(*sorted(volume.items()))
+            data = {}
+            for key, value in volume.to_dict().items():
+                # FIXME(stephenfin): Stop ignoring these once we bump SDK
+                # https://review.opendev.org/c/openstack/openstacksdk/+/945836/
+                if key in (
+                    'cluster_name',
+                    'consumes_quota',
+                    'encryption_key_id',
+                    'service_uuid',
+                    'shared_targets',
+                    'volume_type_id',
+                ):
+                    continue
+                data[key] = value
+            return zip(*sorted(data.items()))
 
         source_volume = None
         if parsed_args.source:
@@ -287,7 +405,7 @@ class CreateVolume(volume_v2.CreateVolum
             description=parsed_args.description,
             volume_type=parsed_args.type,
             availability_zone=parsed_args.availability_zone,
-            metadata=parsed_args.property,
+            metadata=parsed_args.properties,
             imageRef=image,
             source_volid=source_volume,
             consistencygroup_id=consistency_group,
@@ -295,7 +413,7 @@ class CreateVolume(volume_v2.CreateVolum
             backup_id=backup,
         )
 
-        if parsed_args.bootable or parsed_args.non_bootable:
+        if parsed_args.bootable is not None:
             try:
                 if utils.wait_for_status(
                     volume_client.volumes.get,
@@ -309,13 +427,13 @@ class CreateVolume(volume_v2.CreateVolum
                     )
                 else:
                     msg = _(
-                        "Volume status is not available for setting boot "
-                        "state"
+                        "Volume status is not available for setting boot state"
                     )
                     raise exceptions.CommandError(msg)
             except Exception as e:
                 LOG.error(_("Failed to set volume bootable property: %s"), e)
-        if parsed_args.read_only or parsed_args.read_write:
+
+        if parsed_args.read_only is not None:
             try:
                 if utils.wait_for_status(
                     volume_client.volumes.get,
@@ -335,10 +453,7 @@ class CreateVolume(volume_v2.CreateVolum
                     raise exceptions.CommandError(msg)
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to set volume read-only access "
-                        "mode flag: %s"
-                    ),
+                    _("Failed to set volume read-only access mode flag: %s"),
                     e,
                 )
 
@@ -355,12 +470,34 @@ class CreateVolume(volume_v2.CreateVolum
         return zip(*sorted(volume._info.items()))
 
 
-class DeleteVolume(volume_v2.DeleteVolume):
+class DeleteVolume(command.Command):
     _description = _("Delete volume(s)")
 
     def get_parser(self, prog_name):
         parser = super().get_parser(prog_name)
         parser.add_argument(
+            "volumes",
+            metavar="<volume>",
+            nargs="+",
+            help=_("Volume(s) to delete (name or ID)"),
+        )
+        group = parser.add_mutually_exclusive_group()
+        group.add_argument(
+            "--force",
+            action="store_true",
+            help=_(
+                "Attempt forced removal of volume(s), regardless of state "
+                "(defaults to False)"
+            ),
+        )
+        group.add_argument(
+            "--purge",
+            action="store_true",
+            help=_(
+                "Remove any snapshots along with volume(s) (defaults to False)"
+            ),
+        )
+        parser.add_argument(
             '--remote',
             action='store_true',
             help=_("Specify this parameter to unmanage a volume."),
@@ -368,8 +505,7 @@ class DeleteVolume(volume_v2.DeleteVolum
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_client_sdk = self.app.client_manager.sdk_connection.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
         result = 0
 
         if parsed_args.remote and (parsed_args.force or parsed_args.purge):
@@ -379,16 +515,18 @@ class DeleteVolume(volume_v2.DeleteVolum
             )
             raise exceptions.CommandError(msg)
 
-        for i in parsed_args.volumes:
+        for volume in parsed_args.volumes:
             try:
-                volume_obj = utils.find_resource(volume_client.volumes, i)
+                volume_obj = volume_client.find_volume(
+                    volume, ignore_missing=False
+                )
                 if parsed_args.remote:
-                    volume_client_sdk.unmanage_volume(volume_obj.id)
-                elif parsed_args.force:
-                    volume_client.volumes.force_delete(volume_obj.id)
+                    volume_client.unmanage_volume(volume_obj.id)
                 else:
-                    volume_client.volumes.delete(
-                        volume_obj.id, cascade=parsed_args.purge
+                    volume_client.delete_volume(
+                        volume_obj.id,
+                        force=parsed_args.force,
+                        cascade=parsed_args.purge,
                     )
             except Exception as e:
                 result += 1
@@ -397,12 +535,12 @@ class DeleteVolume(volume_v2.DeleteVolum
                         "Failed to delete volume with "
                         "name or ID '%(volume)s': %(e)s"
                     ),
-                    {'volume': i, 'e': e},
+                    {'volume': volume, 'e': e},
                 )
 
         if result > 0:
             total = len(parsed_args.volumes)
-            msg = _("%(result)s of %(total)s volumes failed " "to delete.") % {
+            msg = _("%(result)s of %(total)s volumes failed to delete.") % {
                 'result': result,
                 'total': total,
             }
@@ -437,6 +575,16 @@ class ListVolume(command.Lister):
             help=_('Filter results by status'),
         )
         parser.add_argument(
+            '--property',
+            metavar='<key=value>',
+            action=parseractions.KeyValueAction,
+            dest='properties',
+            help=_(
+                'Filter by a property on the volume list '
+                '(repeat option to filter by multiple properties) '
+            ),
+        )
+        parser.add_argument(
             '--all-projects',
             action='store_true',
             default=False,
@@ -504,6 +652,7 @@ class ListVolume(command.Lister):
             'user_id': user_id,
             'name': parsed_args.name,
             'status': parsed_args.status,
+            'metadata': parsed_args.properties,
         }
 
         data = volume_client.volumes.list(
@@ -523,7 +672,7 @@ class ListVolume(command.Lister):
         server_cache = {}
         if do_server_list:
             try:
-                compute_client = self.app.client_manager.sdk_connection.compute
+                compute_client = self.app.client_manager.compute
                 for s in compute_client.servers():
                     server_cache[s.id] = s
             except sdk_exceptions.SDKException:  # noqa: S110
@@ -642,6 +791,7 @@ class SetVolume(command.Command):
             '--property',
             metavar='<key=value>',
             action=parseractions.KeyValueAction,
+            dest='properties',
             help=_(
                 'Set a property on this volume '
                 '(repeat option to set multiple properties)'
@@ -651,6 +801,7 @@ class SetVolume(command.Command):
             '--image-property',
             metavar='<key=value>',
             action=parseractions.KeyValueAction,
+            dest='image_properties',
             help=_(
                 'Set an image property on this volume '
                 '(repeat option to set multiple image properties)'
@@ -727,22 +878,30 @@ class SetVolume(command.Command):
         bootable_group.add_argument(
             "--bootable",
             action="store_true",
+            dest="bootable",
+            default=None,
             help=_("Mark volume as bootable"),
         )
         bootable_group.add_argument(
             "--non-bootable",
-            action="store_true",
+            action="store_false",
+            dest="bootable",
+            default=None,
             help=_("Mark volume as non-bootable"),
         )
         readonly_group = parser.add_mutually_exclusive_group()
         readonly_group.add_argument(
             "--read-only",
             action="store_true",
+            dest="read_only",
+            default=None,
             help=_("Set volume to read-only access mode"),
         )
         readonly_group.add_argument(
             "--read-write",
-            action="store_true",
+            action="store_false",
+            dest="read_only",
+            default=None,
             help=_("Set volume to read-write access mode"),
         )
         return parser
@@ -768,18 +927,24 @@ class SetVolume(command.Command):
                         _("New size must be greater than %s GB") % volume.size
                     )
                     raise exceptions.CommandError(msg)
-                if (
-                    volume.status != 'available'
-                    and not volume_client.api_version.matches('3.42')
-                ):
+                if volume.status not in ('available', 'in-use'):
                     msg = (
                         _(
                             "Volume is in %s state, it must be available "
-                            "before size can be extended"
+                            "or in-use before size can be extended."
                         )
                         % volume.status
                     )
                     raise exceptions.CommandError(msg)
+                if (
+                    volume.status == 'in-use'
+                    and not volume_client.api_version.matches('3.42')
+                ):
+                    msg = _(
+                        "--os-volume-api-version 3.42 or greater is "
+                        "required to extend in-use volumes."
+                    )
+                    raise exceptions.CommandError(msg)
                 volume_client.volumes.extend(volume.id, parsed_args.size)
             except Exception as e:
                 LOG.error(_("Failed to set volume size: %s"), e)
@@ -794,28 +959,31 @@ class SetVolume(command.Command):
                 LOG.error(_("Failed to clean volume properties: %s"), e)
                 result += 1
 
-        if parsed_args.property:
+        if parsed_args.properties:
             try:
                 volume_client.volumes.set_metadata(
-                    volume.id, parsed_args.property
+                    volume.id, parsed_args.properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to set volume property: %s"), e)
+                LOG.error(_("Failed to set volume properties: %s"), e)
                 result += 1
-        if parsed_args.image_property:
+
+        if parsed_args.image_properties:
             try:
                 volume_client.volumes.set_image_metadata(
-                    volume.id, parsed_args.image_property
+                    volume.id, parsed_args.image_properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to set image property: %s"), e)
+                LOG.error(_("Failed to set image properties: %s"), e)
                 result += 1
+
         if parsed_args.state:
             try:
                 volume_client.volumes.reset_state(volume.id, parsed_args.state)
             except Exception as e:
                 LOG.error(_("Failed to set volume state: %s"), e)
                 result += 1
+
         if parsed_args.attached:
             try:
                 volume_client.volumes.reset_state(
@@ -824,6 +992,7 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume attach-status: %s"), e)
                 result += 1
+
         if parsed_args.detached:
             try:
                 volume_client.volumes.reset_state(
@@ -832,7 +1001,8 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume attach-status: %s"), e)
                 result += 1
-        if parsed_args.bootable or parsed_args.non_bootable:
+
+        if parsed_args.bootable is not None:
             try:
                 volume_client.volumes.set_bootable(
                     volume.id, parsed_args.bootable
@@ -840,20 +1010,19 @@ class SetVolume(command.Command):
             except Exception as e:
                 LOG.error(_("Failed to set volume bootable property: %s"), e)
                 result += 1
-        if parsed_args.read_only or parsed_args.read_write:
+
+        if parsed_args.read_only is not None:
             try:
                 volume_client.volumes.update_readonly_flag(
                     volume.id, parsed_args.read_only
                 )
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to set volume read-only access "
-                        "mode flag: %s"
-                    ),
+                    _("Failed to set volume read-only access mode flag: %s"),
                     e,
                 )
                 result += 1
+
         policy = parsed_args.migration_policy or parsed_args.retype_policy
         if parsed_args.type:
             # get the migration policy
@@ -903,7 +1072,7 @@ class SetVolume(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("One or more of the " "set operations failed")
+                _("One or more of the set operations failed")
             )
 
 
@@ -954,6 +1123,7 @@ class UnsetVolume(command.Command):
             '--property',
             metavar='<key>',
             action='append',
+            dest='properties',
             help=_(
                 'Remove a property from volume '
                 '(repeat option to remove multiple properties)'
@@ -963,6 +1133,7 @@ class UnsetVolume(command.Command):
             '--image-property',
             metavar='<key>',
             action='append',
+            dest='image_properties',
             help=_(
                 'Remove an image property from volume '
                 '(repeat option to remove multiple image properties)'
@@ -975,27 +1146,27 @@ class UnsetVolume(command.Command):
         volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
 
         result = 0
-        if parsed_args.property:
+        if parsed_args.properties:
             try:
                 volume_client.volumes.delete_metadata(
-                    volume.id, parsed_args.property
+                    volume.id, parsed_args.properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to unset volume property: %s"), e)
+                LOG.error(_("Failed to unset volume properties: %s"), e)
                 result += 1
 
-        if parsed_args.image_property:
+        if parsed_args.image_properties:
             try:
                 volume_client.volumes.delete_image_metadata(
-                    volume.id, parsed_args.image_property
+                    volume.id, parsed_args.image_properties
                 )
             except Exception as e:
-                LOG.error(_("Failed to unset image property: %s"), e)
+                LOG.error(_("Failed to unset image properties: %s"), e)
                 result += 1
 
         if result > 0:
             raise exceptions.CommandError(
-                _("One or more of the " "unset operations failed")
+                _("One or more of the unset operations failed")
             )
 
 
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume_attachment.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_attachment.py
--- 7.4.0-3/openstackclient/volume/v3/volume_attachment.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_attachment.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,6 +18,7 @@ from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
 
+from openstackclient.common import envvars
 from openstackclient.common import pagination
 from openstackclient.i18n import _
 from openstackclient.identity import common as identity_common
@@ -171,7 +172,7 @@ class CreateVolumeAttachment(command.Sho
 
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.sdk_connection.volume
-        compute_client = self.app.client_manager.sdk_connection.compute
+        compute_client = self.app.client_manager.compute
 
         if not sdk_utils.supports_microversion(volume_client, '3.27'):
             msg = _(
@@ -399,7 +400,7 @@ class ListVolumeAttachment(command.Liste
             '--all-projects',
             dest='all_projects',
             action='store_true',
-            default=utils.env('ALL_PROJECTS', default=False),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_('Shows details for all projects (admin only).'),
         )
         parser.add_argument(
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume_backup.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_backup.py
--- 7.4.0-3/openstackclient/volume/v3/volume_backup.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_backup.py	2025-07-07 22:41:56.000000000 +0000
@@ -18,7 +18,6 @@ import copy
 import functools
 import logging
 
-from cinderclient import api_versions
 from cliff import columns as cliff_columns
 from openstack import utils as sdk_utils
 from osc_lib.cli import parseractions
@@ -162,7 +161,7 @@ class CreateVolumeBackup(command.ShowOne
 
             kwargs['availability_zone'] = parsed_args.availability_zone
 
-        columns = (
+        columns: tuple[str, ...] = (
             "id",
             "name",
             "volume_id",
@@ -298,7 +297,7 @@ class ListVolumeBackup(command.Lister):
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.sdk_connection.volume
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'name',
             'description',
@@ -307,7 +306,7 @@ class ListVolumeBackup(command.Lister):
             'is_incremental',
             'created_at',
         )
-        column_headers = (
+        column_headers: tuple[str, ...] = (
             'ID',
             'Name',
             'Description',
@@ -403,8 +402,7 @@ class RestoreVolumeBackup(command.ShowOn
             "--force",
             action="store_true",
             help=_(
-                "Restore the backup to an existing volume "
-                "(default to False)"
+                "Restore the backup to an existing volume (default to False)"
             ),
         )
         return parser
@@ -412,7 +410,7 @@ class RestoreVolumeBackup(command.ShowOn
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.sdk_connection.volume
 
-        columns = (
+        columns: tuple[str, ...] = (
             'id',
             'volume_id',
             'volume_name',
@@ -466,7 +464,7 @@ class SetVolumeBackup(command.Command):
             '--name',
             metavar='<name>',
             help=_(
-                'New backup name'
+                'New backup name '
                 '(supported by --os-volume-api-version 3.9 or above)'
             ),
         )
@@ -513,13 +511,19 @@ class SetVolumeBackup(command.Command):
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        backup = utils.find_resource(volume_client.backups, parsed_args.backup)
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        backup = volume_client.find_backup(
+            parsed_args.backup,
+            ignore_missing=False,
+        )
 
         result = 0
         if parsed_args.state:
             try:
-                volume_client.backups.reset_state(backup.id, parsed_args.state)
+                volume_client.reset_backup_status(
+                    backup, status=parsed_args.state
+                )
             except Exception as e:
                 LOG.error(_("Failed to set backup state: %s"), e)
                 result += 1
@@ -527,7 +531,7 @@ class SetVolumeBackup(command.Command):
         kwargs = {}
 
         if parsed_args.name:
-            if volume_client.api_version < api_versions.APIVersion('3.9'):
+            if not sdk_utils.supports_microversion(volume_client, '3.9'):
                 msg = _(
                     '--os-volume-api-version 3.9 or greater is required to '
                     'support the --name option'
@@ -537,7 +541,7 @@ class SetVolumeBackup(command.Command):
             kwargs['name'] = parsed_args.name
 
         if parsed_args.description:
-            if volume_client.api_version < api_versions.APIVersion('3.9'):
+            if not sdk_utils.supports_microversion(volume_client, '3.9'):
                 msg = _(
                     '--os-volume-api-version 3.9 or greater is required to '
                     'support the --description option'
@@ -547,7 +551,7 @@ class SetVolumeBackup(command.Command):
             kwargs['description'] = parsed_args.description
 
         if parsed_args.no_property:
-            if volume_client.api_version < api_versions.APIVersion('3.43'):
+            if not sdk_utils.supports_microversion(volume_client, '3.43'):
                 msg = _(
                     '--os-volume-api-version 3.43 or greater is required to '
                     'support the --no-property option'
@@ -555,14 +559,14 @@ class SetVolumeBackup(command.Command):
                 raise exceptions.CommandError(msg)
 
         if parsed_args.properties:
-            if volume_client.api_version < api_versions.APIVersion('3.43'):
+            if not sdk_utils.supports_microversion(volume_client, '3.43'):
                 msg = _(
                     '--os-volume-api-version 3.43 or greater is required to '
                     'support the --property option'
                 )
                 raise exceptions.CommandError(msg)
 
-        if volume_client.api_version >= api_versions.APIVersion('3.43'):
+        if sdk_utils.supports_microversion(volume_client, '3.43'):
             metadata = copy.deepcopy(backup.metadata)
 
             if parsed_args.no_property:
@@ -573,7 +577,7 @@ class SetVolumeBackup(command.Command):
 
         if kwargs:
             try:
-                volume_client.backups.update(backup.id, **kwargs)
+                volume_client.update_backup(backup, **kwargs)
             except Exception as e:
                 LOG.error("Failed to update backup: %s", e)
                 result += 1
@@ -609,16 +613,18 @@ class UnsetVolumeBackup(command.Command)
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
+        volume_client = self.app.client_manager.sdk_connection.volume
 
-        if volume_client.api_version < api_versions.APIVersion('3.43'):
+        if not sdk_utils.supports_microversion(volume_client, '3.43'):
             msg = _(
                 '--os-volume-api-version 3.43 or greater is required to '
                 'support the --property option'
             )
             raise exceptions.CommandError(msg)
 
-        backup = utils.find_resource(volume_client.backups, parsed_args.backup)
+        backup = volume_client.find_backup(
+            parsed_args.backup, ignore_missing=False
+        )
         metadata = copy.deepcopy(backup.metadata)
 
         for key in parsed_args.properties:
@@ -633,11 +639,7 @@ class UnsetVolumeBackup(command.Command)
 
             del metadata[key]
 
-        kwargs = {
-            'metadata': metadata,
-        }
-
-        volume_client.backups.update(backup.id, **kwargs)
+        volume_client.delete_backup_metadata(backup, keys=list(metadata))
 
 
 class ShowVolumeBackup(command.ShowOne):
@@ -654,8 +656,10 @@ class ShowVolumeBackup(command.ShowOne):
 
     def take_action(self, parsed_args):
         volume_client = self.app.client_manager.sdk_connection.volume
-        backup = volume_client.find_backup(parsed_args.backup)
-        columns = (
+        backup = volume_client.find_backup(
+            parsed_args.backup, ignore_missing=False
+        )
+        columns: tuple[str, ...] = (
             "availability_zone",
             "container",
             "created_at",
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume_group.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_group.py
--- 7.4.0-3/openstackclient/volume/v3/volume_group.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_group.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@ from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
 
+from openstackclient.common import envvars
 from openstackclient.i18n import _
 
 
@@ -410,7 +411,7 @@ class ListVolumeGroup(command.Lister):
             '--all-projects',
             dest='all_projects',
             action='store_true',
-            default=utils.env('ALL_PROJECTS', default=False),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_('Shows details for all projects (admin only).'),
         )
         # TODO(stephenfin): Add once we have an equivalent command for
@@ -551,7 +552,7 @@ class ShowVolumeGroup(command.ShowOne):
             parsed_args.group,
         )
 
-        group = volume_client.groups.show(group.id, **kwargs)
+        group = volume_client.groups.get(group.id, **kwargs)
 
         if parsed_args.show_replication_targets:
             replication_targets = (
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume_group_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_group_snapshot.py
--- 7.4.0-3/openstackclient/volume/v3/volume_group_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_group_snapshot.py	2025-07-07 22:41:56.000000000 +0000
@@ -17,6 +17,7 @@ from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
 
+from openstackclient.common import envvars
 from openstackclient.i18n import _
 
 LOG = logging.getLogger(__name__)
@@ -145,7 +146,7 @@ class ListVolumeGroupSnapshot(command.Li
             '--all-projects',
             dest='all_projects',
             action='store_true',
-            default=utils.env('ALL_PROJECTS', default=False),
+            default=envvars.boolenv('ALL_PROJECTS'),
             help=_('Shows details for all projects (admin only).'),
         )
         # TODO(stephenfin): Add once we have an equivalent command for
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume_snapshot.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_snapshot.py
--- 7.4.0-3/openstackclient/volume/v3/volume_snapshot.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_snapshot.py	2025-07-07 22:41:56.000000000 +0000
@@ -14,17 +14,180 @@
 
 """Volume v3 snapshot action implementations"""
 
+import functools
 import logging
+import typing as ty
 
+from cliff import columns as cliff_columns
+from openstack.block_storage.v3 import snapshot as _snapshot
+from osc_lib.cli import format_columns
+from osc_lib.cli import parseractions
 from osc_lib.command import command
 from osc_lib import exceptions
 from osc_lib import utils
 
+from openstackclient.common import pagination
 from openstackclient.i18n import _
+from openstackclient.identity import common as identity_common
 
 LOG = logging.getLogger(__name__)
 
 
+class VolumeIdColumn(cliff_columns.FormattableColumn):
+    """Formattable column for volume ID column.
+
+    Unlike the parent FormattableColumn class, the initializer of the
+    class takes volume_cache as the second argument.
+    osc_lib.utils.get_item_properties instantiate cliff FormattableColumn
+    object with a single parameter "column value", so you need to pass
+    a partially initialized class like
+    ``functools.partial(VolumeIdColumn, volume_cache)``.
+    """
+
+    def __init__(self, value, volume_cache=None):
+        super().__init__(value)
+        self._volume_cache = volume_cache or {}
+
+    def human_readable(self):
+        """Return a volume name if available
+
+        :rtype: either the volume ID or name
+        """
+        volume_id = self._value
+        volume = volume_id
+        if volume_id in self._volume_cache.keys():
+            volume = self._volume_cache[volume_id].name
+        return volume
+
+
+def _format_snapshot(snapshot: _snapshot.Snapshot) -> dict[str, ty.Any]:
+    # Some columns returned by openstacksdk should not be shown because they're
+    # either irrelevant or duplicates
+    ignored_columns = {
+        # computed columns
+        'location',
+        # create-only columns
+        'consumes_quota',
+        'force',
+        'group_snapshot_id',
+        # ignored columns
+        'os-extended-snapshot-attributes:progress',
+        'os-extended-snapshot-attributes:project_id',
+        'updated_at',
+        'user_id',
+        # unnecessary columns
+        'links',
+    }
+
+    info = snapshot.to_dict(original_names=True)
+    data = {}
+    for key, value in info.items():
+        if key in ignored_columns:
+            continue
+
+        data[key] = value
+
+    data.update(
+        {
+            'properties': format_columns.DictColumn(data.pop('metadata')),
+        }
+    )
+
+    return data
+
+
+class CreateVolumeSnapshot(command.ShowOne):
+    _description = _("Create new volume snapshot")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "snapshot_name",
+            metavar="<snapshot-name>",
+            help=_("Name of the new snapshot"),
+        )
+        parser.add_argument(
+            "--volume",
+            metavar="<volume>",
+            help=_(
+                "Volume to snapshot (name or ID) (default is <snapshot-name>)"
+            ),
+        )
+        parser.add_argument(
+            "--description",
+            metavar="<description>",
+            help=_("Description of the snapshot"),
+        )
+        parser.add_argument(
+            "--force",
+            action="store_true",
+            default=False,
+            help=_(
+                "Create a snapshot attached to an instance. Default is False"
+            ),
+        )
+        parser.add_argument(
+            "--property",
+            metavar="<key=value>",
+            dest='properties',
+            action=parseractions.KeyValueAction,
+            help=_(
+                "Set a property to this snapshot "
+                "(repeat option to set multiple properties)"
+            ),
+        )
+        parser.add_argument(
+            "--remote-source",
+            metavar="<key=value>",
+            action=parseractions.KeyValueAction,
+            help=_(
+                "The attribute(s) of the existing remote volume snapshot "
+                "(admin required) (repeat option to specify multiple "
+                "attributes) e.g.: '--remote-source source-name=test_name "
+                "--remote-source source-id=test_id'"
+            ),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        volume = parsed_args.volume
+        if not parsed_args.volume:
+            volume = parsed_args.snapshot_name
+        volume_id = volume_client.find_volume(volume, ignore_missing=False).id
+
+        if parsed_args.remote_source:
+            # Create a new snapshot from an existing remote snapshot source
+            if parsed_args.force:
+                msg = _(
+                    "'--force' option will not work when you create "
+                    "new volume snapshot from an existing remote "
+                    "volume snapshot"
+                )
+                LOG.warning(msg)
+
+            snapshot = volume_client.manage_snapshot(
+                volume_id=volume_id,
+                ref=parsed_args.remote_source,
+                name=parsed_args.snapshot_name,
+                description=parsed_args.description,
+                metadata=parsed_args.properties,
+            )
+        else:
+            # Create a new snapshot from scratch
+            snapshot = volume_client.create_snapshot(
+                volume_id=volume_id,
+                force=parsed_args.force,
+                name=parsed_args.snapshot_name,
+                description=parsed_args.description,
+                metadata=parsed_args.properties,
+            )
+
+        data = _format_snapshot(snapshot)
+        return zip(*sorted(data.items()))
+
+
 class DeleteVolumeSnapshot(command.Command):
     _description = _("Delete volume snapshot(s)")
 
@@ -55,9 +218,7 @@ class DeleteVolumeSnapshot(command.Comma
         return parser
 
     def take_action(self, parsed_args):
-        volume_client = self.app.client_manager.volume
-        volume_client_sdk = self.app.client_manager.sdk_connection.volume
-
+        volume_client = self.app.client_manager.sdk_connection.volume
         result = 0
 
         if parsed_args.remote:
@@ -68,16 +229,16 @@ class DeleteVolumeSnapshot(command.Comma
                 )
                 raise exceptions.CommandError(msg)
 
-        for i in parsed_args.snapshots:
+        for snapshot in parsed_args.snapshots:
             try:
-                snapshot_id = utils.find_resource(
-                    volume_client.volume_snapshots, i
+                snapshot_id = volume_client.find_snapshot(
+                    snapshot, ignore_missing=False
                 ).id
                 if parsed_args.remote:
-                    volume_client_sdk.unmanage_snapshot(snapshot_id)
+                    volume_client.unmanage_snapshot(snapshot_id)
                 else:
-                    volume_client.volume_snapshots.delete(
-                        snapshot_id, parsed_args.force
+                    volume_client.delete_snapshot(
+                        snapshot_id, force=parsed_args.force
                     )
             except Exception as e:
                 result += 1
@@ -86,12 +247,327 @@ class DeleteVolumeSnapshot(command.Comma
                         "Failed to delete snapshot with "
                         "name or ID '%(snapshot)s': %(e)s"
                     )
-                    % {'snapshot': i, 'e': e}
+                    % {'snapshot': snapshot, 'e': e}
                 )
 
         if result > 0:
             total = len(parsed_args.snapshots)
-            msg = _(
-                "%(result)s of %(total)s snapshots failed " "to delete."
-            ) % {'result': result, 'total': total}
+            msg = _("%(result)s of %(total)s snapshots failed to delete.") % {
+                'result': result,
+                'total': total,
+            }
             raise exceptions.CommandError(msg)
+
+
+class ListVolumeSnapshot(command.Lister):
+    _description = _("List volume snapshots")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            '--all-projects',
+            action='store_true',
+            default=False,
+            help=_('Include all projects (admin only)'),
+        )
+        parser.add_argument(
+            '--project',
+            metavar='<project>',
+            help=_('Filter results by project (name or ID) (admin only)'),
+        )
+        identity_common.add_project_domain_option_to_parser(parser)
+        parser.add_argument(
+            '--long',
+            action='store_true',
+            default=False,
+            help=_('List additional fields in output'),
+        )
+        parser.add_argument(
+            '--name',
+            metavar='<name>',
+            default=None,
+            help=_('Filters results by a name.'),
+        )
+        parser.add_argument(
+            '--status',
+            metavar='<status>',
+            choices=[
+                'available',
+                'error',
+                'creating',
+                'deleting',
+                'error_deleting',
+            ],
+            help=_(
+                "Filters results by a status. "
+                "('available', 'error', 'creating', 'deleting'"
+                " or 'error_deleting')"
+            ),
+        )
+        parser.add_argument(
+            '--volume',
+            metavar='<volume>',
+            default=None,
+            help=_('Filters results by a volume (name or ID).'),
+        )
+        pagination.add_marker_pagination_option_to_parser(parser)
+        return parser
+
+    def take_action(self, parsed_args):
+        volume_client = self.app.client_manager.sdk_connection.volume
+        identity_client = self.app.client_manager.identity
+
+        columns: tuple[str, ...] = (
+            'id',
+            'name',
+            'description',
+            'status',
+            'size',
+        )
+        column_headers: tuple[str, ...] = (
+            'ID',
+            'Name',
+            'Description',
+            'Status',
+            'Size',
+        )
+        if parsed_args.long:
+            columns += (
+                'created_at',
+                'volume_id',
+                'metadata',
+            )
+            column_headers += (
+                'Created At',
+                'Volume',
+                'Properties',
+            )
+
+        # Cache the volume list
+        volume_cache = {}
+        try:
+            for s in volume_client.volumes():
+                volume_cache[s.id] = s
+        except Exception:  # noqa: S110
+            # Just forget it if there's any trouble
+            pass
+        _VolumeIdColumn = functools.partial(
+            VolumeIdColumn, volume_cache=volume_cache
+        )
+
+        volume_id = None
+        if parsed_args.volume:
+            volume_id = volume_client.find_volume(
+                parsed_args.volume, ignore_missing=False
+            ).id
+
+        project_id = None
+        if parsed_args.project:
+            project_id = identity_common.find_project(
+                identity_client,
+                parsed_args.project,
+                parsed_args.project_domain,
+            ).id
+
+        # set value of 'all_tenants' when using project option
+        all_projects = (
+            True if parsed_args.project else parsed_args.all_projects
+        )
+
+        data = volume_client.snapshots(
+            marker=parsed_args.marker,
+            limit=parsed_args.limit,
+            all_projects=all_projects,
+            project_id=project_id,
+            name=parsed_args.name,
+            status=parsed_args.status,
+            volume_id=volume_id,
+        )
+        return (
+            column_headers,
+            (
+                utils.get_item_properties(
+                    s,
+                    columns,
+                    formatters={
+                        'metadata': format_columns.DictColumn,
+                        'volume_id': _VolumeIdColumn,
+                    },
+                )
+                for s in data
+            ),
+        )
+
+
+class SetVolumeSnapshot(command.Command):
+    _description = _("Set volume snapshot properties")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            'snapshot',
+            metavar='<snapshot>',
+            help=_('Snapshot to modify (name or ID)'),
+        )
+        parser.add_argument(
+            '--name', metavar='<name>', help=_('New snapshot name')
+        )
+        parser.add_argument(
+            '--description',
+            metavar='<description>',
+            help=_('New snapshot description'),
+        )
+        parser.add_argument(
+            "--no-property",
+            dest="no_property",
+            action="store_true",
+            help=_(
+                "Remove all properties from <snapshot> "
+                "(specify both --no-property and --property to "
+                "remove the current properties before setting "
+                "new properties.)"
+            ),
+        )
+        parser.add_argument(
+            '--property',
+            metavar='<key=value>',
+            action=parseractions.KeyValueAction,
+            dest='properties',
+            help=_(
+                'Property to add/change for this snapshot '
+                '(repeat option to set multiple properties)'
+            ),
+        )
+        parser.add_argument(
+            '--state',
+            metavar='<state>',
+            choices=[
+                'available',
+                'error',
+                'creating',
+                'deleting',
+                'error_deleting',
+            ],
+            help=_(
+                'New snapshot state. ("available", "error", "creating", '
+                '"deleting", or "error_deleting") (admin only) '
+                '(This option simply changes the state of the snapshot '
+                'in the database with no regard to actual status, '
+                'exercise caution when using)'
+            ),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        snapshot = volume_client.find_snapshot(
+            parsed_args.snapshot, ignore_missing=False
+        )
+
+        result = 0
+        if parsed_args.no_property:
+            try:
+                volume_client.delete_snapshot_metadata(
+                    snapshot.id, keys=list(snapshot.metadata)
+                )
+            except Exception as e:
+                LOG.error(_("Failed to clean snapshot properties: %s"), e)
+                result += 1
+
+        if parsed_args.properties:
+            try:
+                volume_client.set_snapshot_metadata(
+                    snapshot.id, **parsed_args.properties
+                )
+            except Exception as e:
+                LOG.error(_("Failed to set snapshot property: %s"), e)
+                result += 1
+
+        if parsed_args.state:
+            try:
+                volume_client.reset_snapshot_status(
+                    snapshot.id, parsed_args.state
+                )
+            except Exception as e:
+                LOG.error(_("Failed to set snapshot state: %s"), e)
+                result += 1
+
+        kwargs = {}
+        if parsed_args.name:
+            kwargs['name'] = parsed_args.name
+        if parsed_args.description:
+            kwargs['description'] = parsed_args.description
+        if kwargs:
+            try:
+                volume_client.update_snapshot(snapshot.id, **kwargs)
+            except Exception as e:
+                LOG.error(
+                    _("Failed to update snapshot name or description: %s"),
+                    e,
+                )
+                result += 1
+
+        if result > 0:
+            raise exceptions.CommandError(
+                _("One or more of the set operations failed")
+            )
+
+
+class ShowVolumeSnapshot(command.ShowOne):
+    _description = _("Display volume snapshot details")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "snapshot",
+            metavar="<snapshot>",
+            help=_("Snapshot to display (name or ID)"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        snapshot = volume_client.find_snapshot(
+            parsed_args.snapshot, ignore_missing=False
+        )
+
+        data = _format_snapshot(snapshot)
+        return zip(*sorted(data.items()))
+
+
+class UnsetVolumeSnapshot(command.Command):
+    _description = _("Unset volume snapshot properties")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            'snapshot',
+            metavar='<snapshot>',
+            help=_('Snapshot to modify (name or ID)'),
+        )
+        parser.add_argument(
+            '--property',
+            metavar='<key>',
+            dest='properties',
+            action='append',
+            default=[],
+            help=_(
+                'Property to remove from snapshot '
+                '(repeat option to remove multiple properties)'
+            ),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        volume_client = self.app.client_manager.sdk_connection.volume
+
+        snapshot = volume_client.find_snapshot(
+            parsed_args.snapshot, ignore_missing=False
+        )
+
+        if parsed_args.properties:
+            volume_client.delete_snapshot_metadata(
+                snapshot.id, keys=parsed_args.properties
+            )
diff -pruN 7.4.0-3/openstackclient/volume/v3/volume_type.py 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_type.py
--- 7.4.0-3/openstackclient/volume/v3/volume_type.py	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/openstackclient/volume/v3/volume_type.py	2025-07-07 22:41:56.000000000 +0000
@@ -273,8 +273,7 @@ class CreateVolumeType(command.ShowOne):
                 )
             except Exception as e:
                 msg = _(
-                    "Failed to add project %(project)s access to "
-                    "type: %(e)s"
+                    "Failed to add project %(project)s access to type: %(e)s"
                 )
                 LOG.error(msg % {'project': parsed_args.project, 'e': e})
 
@@ -364,7 +363,7 @@ class DeleteVolumeType(command.Command):
         if result > 0:
             total = len(parsed_args.volume_types)
             msg = _(
-                "%(result)s of %(total)s volume types failed " "to delete."
+                "%(result)s of %(total)s volume types failed to delete."
             ) % {'result': result, 'total': total}
             raise exceptions.CommandError(msg)
 
@@ -635,8 +634,7 @@ class SetVolumeType(command.Command):
             '--project',
             metavar='<project>',
             help=_(
-                'Set volume type access to project (name or ID) '
-                '(admin only)'
+                'Set volume type access to project (name or ID) (admin only)'
             ),
         )
         public_group = parser.add_mutually_exclusive_group()
@@ -728,17 +726,12 @@ class SetVolumeType(command.Command):
                 volume_client.volume_types.update(volume_type.id, **kwargs)
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to update volume type name or"
-                        " description: %s"
-                    ),
+                    _("Failed to update volume type name or description: %s"),
                     e,
                 )
                 result += 1
 
-        properties = {}
-
-        properties = {}
+        properties: dict[str, str] = {}
         if parsed_args.properties:
             properties.update(parsed_args.properties)
         if parsed_args.multiattach:
@@ -772,7 +765,7 @@ class SetVolumeType(command.Command):
                 )
             except Exception as e:
                 LOG.error(
-                    _("Failed to set volume type access to " "project: %s"), e
+                    _("Failed to set volume type access to project: %s"), e
                 )
                 result += 1
 
@@ -796,7 +789,7 @@ class SetVolumeType(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
+                _("Command Failed: One or more of the operations failed")
             )
 
 
@@ -904,8 +897,7 @@ class UnsetVolumeType(command.Command):
             "--encryption-type",
             action="store_true",
             help=_(
-                "Remove the encryption type for this volume type "
-                "(admin only)"
+                "Remove the encryption type for this volume type (admin only)"
             ),
         )
         return parser
@@ -941,10 +933,7 @@ class UnsetVolumeType(command.Command):
                 )
             except Exception as e:
                 LOG.error(
-                    _(
-                        "Failed to remove volume type access from "
-                        "project: %s"
-                    ),
+                    _("Failed to remove volume type access from project: %s"),
                     e,
                 )
                 result += 1
@@ -963,5 +952,5 @@ class UnsetVolumeType(command.Command):
 
         if result > 0:
             raise exceptions.CommandError(
-                _("Command Failed: One or more of" " the operations failed")
+                _("Command Failed: One or more of the operations failed")
             )
diff -pruN 7.4.0-3/pyproject.toml 8.1.0+git2025070715.9d3a956a-0ubuntu2/pyproject.toml
--- 7.4.0-3/pyproject.toml	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/pyproject.toml	2025-07-07 22:41:56.000000000 +0000
@@ -1,3 +1,745 @@
+[build-system]
+requires = ["pbr>=6.1.1"]
+build-backend = "pbr.build"
+
+[project]
+name = "python-openstackclient"
+description = "OpenStack Command-line Client"
+authors = [
+    {name = "OpenStack", email = "openstack-discuss@lists.openstack.org"},
+]
+readme = {file = "README.rst", content-type = "text/x-rst"}
+license = {text = "Apache-2.0"}
+dynamic = ["version", "dependencies"]
+# dependencies = [ ]
+requires-python = ">=3.10"
+classifiers = [
+  "Environment :: OpenStack",
+  "Intended Audience :: Information Technology",
+  "Intended Audience :: System Administrators",
+  "License :: OSI Approved :: Apache Software License",
+  "Operating System :: POSIX :: Linux",
+  "Programming Language :: Python",
+  "Programming Language :: Python :: 3",
+  "Programming Language :: Python :: 3.10",
+  "Programming Language :: Python :: 3.11",
+  "Programming Language :: Python :: 3.12",
+  "Programming Language :: Python :: 3.13",
+]
+
+# [project.optional-dependencies]
+# test = [
+# ]
+
+[project.urls]
+Homepage = "https://docs.openstack.org/python-openstackclient/"
+Repository = "https://opendev.org/openstack/python-openstackclient/"
+
+[project.scripts]
+openstack = "openstackclient.shell:main"
+
+[project.entry-points."openstack.cli"]
+command_list = "openstackclient.common.module:ListCommand"
+module_list = "openstackclient.common.module:ListModule"
+
+[project.entry-points."openstack.cli.base"]
+compute = "openstackclient.compute.client"
+identity = "openstackclient.identity.client"
+image = "openstackclient.image.client"
+network = "openstackclient.network.client"
+object_store = "openstackclient.object.client"
+volume = "openstackclient.volume.client"
+
+[project.entry-points."openstack.common"]
+availability_zone_list = "openstackclient.common.availability_zone:ListAvailabilityZone"
+configuration_show = "openstackclient.common.configuration:ShowConfiguration"
+extension_list = "openstackclient.common.extension:ListExtension"
+extension_show = "openstackclient.common.extension:ShowExtension"
+limits_show = "openstackclient.common.limits:ShowLimits"
+project_cleanup = "openstackclient.common.project_cleanup:ProjectCleanup"
+quota_list = "openstackclient.common.quota:ListQuota"
+quota_set = "openstackclient.common.quota:SetQuota"
+quota_show = "openstackclient.common.quota:ShowQuota"
+quota_delete = "openstackclient.common.quota:DeleteQuota"
+versions_show = "openstackclient.common.versions:ShowVersions"
+
+[project.entry-points."openstack.compute.v2"]
+aggregate_add_host = "openstackclient.compute.v2.aggregate:AddAggregateHost"
+aggregate_create = "openstackclient.compute.v2.aggregate:CreateAggregate"
+aggregate_delete = "openstackclient.compute.v2.aggregate:DeleteAggregate"
+aggregate_list = "openstackclient.compute.v2.aggregate:ListAggregate"
+aggregate_remove_host = "openstackclient.compute.v2.aggregate:RemoveAggregateHost"
+aggregate_set = "openstackclient.compute.v2.aggregate:SetAggregate"
+aggregate_show = "openstackclient.compute.v2.aggregate:ShowAggregate"
+aggregate_unset = "openstackclient.compute.v2.aggregate:UnsetAggregate"
+aggregate_cache_image = "openstackclient.compute.v2.aggregate:CacheImageForAggregate"
+compute_agent_create = "openstackclient.compute.v2.agent:CreateAgent"
+compute_agent_delete = "openstackclient.compute.v2.agent:DeleteAgent"
+compute_agent_list = "openstackclient.compute.v2.agent:ListAgent"
+compute_agent_set = "openstackclient.compute.v2.agent:SetAgent"
+compute_service_delete = "openstackclient.compute.v2.service:DeleteService"
+compute_service_list = "openstackclient.compute.v2.service:ListService"
+compute_service_set = "openstackclient.compute.v2.service:SetService"
+console_log_show = "openstackclient.compute.v2.console:ShowConsoleLog"
+console_url_show = "openstackclient.compute.v2.console:ShowConsoleURL"
+console_connection_show = "openstackclient.compute.v2.console_connection:ShowConsoleConnectionInformation"
+flavor_create = "openstackclient.compute.v2.flavor:CreateFlavor"
+flavor_delete = "openstackclient.compute.v2.flavor:DeleteFlavor"
+flavor_list = "openstackclient.compute.v2.flavor:ListFlavor"
+flavor_show = "openstackclient.compute.v2.flavor:ShowFlavor"
+flavor_set = "openstackclient.compute.v2.flavor:SetFlavor"
+flavor_unset = "openstackclient.compute.v2.flavor:UnsetFlavor"
+host_list = "openstackclient.compute.v2.host:ListHost"
+host_set = "openstackclient.compute.v2.host:SetHost"
+host_show = "openstackclient.compute.v2.host:ShowHost"
+hypervisor_list = "openstackclient.compute.v2.hypervisor:ListHypervisor"
+hypervisor_show = "openstackclient.compute.v2.hypervisor:ShowHypervisor"
+hypervisor_stats_show = "openstackclient.compute.v2.hypervisor_stats:ShowHypervisorStats"
+keypair_create = "openstackclient.compute.v2.keypair:CreateKeypair"
+keypair_delete = "openstackclient.compute.v2.keypair:DeleteKeypair"
+keypair_list = "openstackclient.compute.v2.keypair:ListKeypair"
+keypair_show = "openstackclient.compute.v2.keypair:ShowKeypair"
+server_add_fixed_ip = "openstackclient.compute.v2.server:AddFixedIP"
+server_add_floating_ip = "openstackclient.compute.v2.server:AddFloatingIP"
+server_add_port = "openstackclient.compute.v2.server:AddPort"
+server_add_network = "openstackclient.compute.v2.server:AddNetwork"
+server_add_security_group = "openstackclient.compute.v2.server:AddServerSecurityGroup"
+server_add_volume = "openstackclient.compute.v2.server:AddServerVolume"
+server_create = "openstackclient.compute.v2.server:CreateServer"
+server_delete = "openstackclient.compute.v2.server:DeleteServer"
+server_dump_create = "openstackclient.compute.v2.server:CreateServerDump"
+server_evacuate = "openstackclient.compute.v2.server:EvacuateServer"
+server_list = "openstackclient.compute.v2.server:ListServer"
+server_lock = "openstackclient.compute.v2.server:LockServer"
+server_migrate = "openstackclient.compute.v2.server:MigrateServer"
+server_migrate_confirm = "openstackclient.compute.v2.server:MigrateConfirm"
+server_migrate_revert = "openstackclient.compute.v2.server:MigrateRevert"
+server_migration_confirm = "openstackclient.compute.v2.server:ConfirmMigration"
+server_migration_revert = "openstackclient.compute.v2.server:RevertMigration"
+server_pause = "openstackclient.compute.v2.server:PauseServer"
+server_reboot = "openstackclient.compute.v2.server:RebootServer"
+server_rebuild = "openstackclient.compute.v2.server:RebuildServer"
+server_remove_fixed_ip = "openstackclient.compute.v2.server:RemoveFixedIP"
+server_remove_floating_ip = "openstackclient.compute.v2.server:RemoveFloatingIP"
+server_remove_port = "openstackclient.compute.v2.server:RemovePort"
+server_remove_network = "openstackclient.compute.v2.server:RemoveNetwork"
+server_remove_security_group = "openstackclient.compute.v2.server:RemoveServerSecurityGroup"
+server_remove_volume = "openstackclient.compute.v2.server:RemoveServerVolume"
+server_rescue = "openstackclient.compute.v2.server:RescueServer"
+server_resize = "openstackclient.compute.v2.server:ResizeServer"
+server_resize_confirm = "openstackclient.compute.v2.server:ResizeConfirm"
+server_resize_revert = "openstackclient.compute.v2.server:ResizeRevert"
+server_restore = "openstackclient.compute.v2.server:RestoreServer"
+server_resume = "openstackclient.compute.v2.server:ResumeServer"
+server_set = "openstackclient.compute.v2.server:SetServer"
+server_shelve = "openstackclient.compute.v2.server:ShelveServer"
+server_show = "openstackclient.compute.v2.server:ShowServer"
+server_ssh = "openstackclient.compute.v2.server:SshServer"
+server_start = "openstackclient.compute.v2.server:StartServer"
+server_stop = "openstackclient.compute.v2.server:StopServer"
+server_suspend = "openstackclient.compute.v2.server:SuspendServer"
+server_unlock = "openstackclient.compute.v2.server:UnlockServer"
+server_unpause = "openstackclient.compute.v2.server:UnpauseServer"
+server_unrescue = "openstackclient.compute.v2.server:UnrescueServer"
+server_unset = "openstackclient.compute.v2.server:UnsetServer"
+server_unshelve = "openstackclient.compute.v2.server:UnshelveServer"
+server_backup_create = "openstackclient.compute.v2.server_backup:CreateServerBackup"
+server_event_list = "openstackclient.compute.v2.server_event:ListServerEvent"
+server_event_show = "openstackclient.compute.v2.server_event:ShowServerEvent"
+server_group_create = "openstackclient.compute.v2.server_group:CreateServerGroup"
+server_group_delete = "openstackclient.compute.v2.server_group:DeleteServerGroup"
+server_group_list = "openstackclient.compute.v2.server_group:ListServerGroup"
+server_group_show = "openstackclient.compute.v2.server_group:ShowServerGroup"
+server_image_create = "openstackclient.compute.v2.server_image:CreateServerImage"
+server_migration_abort = "openstackclient.compute.v2.server_migration:AbortMigration"
+server_migration_force_complete = "openstackclient.compute.v2.server_migration:ForceCompleteMigration"
+server_migration_list = "openstackclient.compute.v2.server_migration:ListMigration"
+server_migration_show = "openstackclient.compute.v2.server_migration:ShowMigration"
+server_volume_list = "openstackclient.compute.v2.server_volume:ListServerVolume"
+server_volume_set = "openstackclient.compute.v2.server_volume:SetServerVolume"
+server_volume_update = "openstackclient.compute.v2.server_volume:UpdateServerVolume"
+usage_list = "openstackclient.compute.v2.usage:ListUsage"
+usage_show = "openstackclient.compute.v2.usage:ShowUsage"
+
+[project.entry-points."openstack.identity.v2"]
+catalog_list = "openstackclient.identity.v2_0.catalog:ListCatalog"
+catalog_show = "openstackclient.identity.v2_0.catalog:ShowCatalog"
+ec2_credentials_create = "openstackclient.identity.v2_0.ec2creds:CreateEC2Creds"
+ec2_credentials_delete = "openstackclient.identity.v2_0.ec2creds:DeleteEC2Creds"
+ec2_credentials_list = "openstackclient.identity.v2_0.ec2creds:ListEC2Creds"
+ec2_credentials_show = "openstackclient.identity.v2_0.ec2creds:ShowEC2Creds"
+endpoint_create = "openstackclient.identity.v2_0.endpoint:CreateEndpoint"
+endpoint_delete = "openstackclient.identity.v2_0.endpoint:DeleteEndpoint"
+endpoint_list = "openstackclient.identity.v2_0.endpoint:ListEndpoint"
+endpoint_show = "openstackclient.identity.v2_0.endpoint:ShowEndpoint"
+project_create = "openstackclient.identity.v2_0.project:CreateProject"
+project_delete = "openstackclient.identity.v2_0.project:DeleteProject"
+project_list = "openstackclient.identity.v2_0.project:ListProject"
+project_set = "openstackclient.identity.v2_0.project:SetProject"
+project_show = "openstackclient.identity.v2_0.project:ShowProject"
+project_unset = "openstackclient.identity.v2_0.project:UnsetProject"
+role_add = "openstackclient.identity.v2_0.role:AddRole"
+role_create = "openstackclient.identity.v2_0.role:CreateRole"
+role_delete = "openstackclient.identity.v2_0.role:DeleteRole"
+role_list = "openstackclient.identity.v2_0.role:ListRole"
+role_remove = "openstackclient.identity.v2_0.role:RemoveRole"
+role_show = "openstackclient.identity.v2_0.role:ShowRole"
+role_assignment_list = "openstackclient.identity.v2_0.role_assignment:ListRoleAssignment"
+service_create = "openstackclient.identity.v2_0.service:CreateService"
+service_delete = "openstackclient.identity.v2_0.service:DeleteService"
+service_list = "openstackclient.identity.v2_0.service:ListService"
+service_show = "openstackclient.identity.v2_0.service:ShowService"
+token_issue = "openstackclient.identity.v2_0.token:IssueToken"
+token_revoke = "openstackclient.identity.v2_0.token:RevokeToken"
+user_create = "openstackclient.identity.v2_0.user:CreateUser"
+user_delete = "openstackclient.identity.v2_0.user:DeleteUser"
+user_list = "openstackclient.identity.v2_0.user:ListUser"
+user_set = "openstackclient.identity.v2_0.user:SetUser"
+user_show = "openstackclient.identity.v2_0.user:ShowUser"
+
+[project.entry-points."openstack.identity.v3"]
+access_token_create = "openstackclient.identity.v3.token:CreateAccessToken"
+access_rule_delete = "openstackclient.identity.v3.access_rule:DeleteAccessRule"
+access_rule_list = "openstackclient.identity.v3.access_rule:ListAccessRule"
+access_rule_show = "openstackclient.identity.v3.access_rule:ShowAccessRule"
+application_credential_create = "openstackclient.identity.v3.application_credential:CreateApplicationCredential"
+application_credential_delete = "openstackclient.identity.v3.application_credential:DeleteApplicationCredential"
+application_credential_list = "openstackclient.identity.v3.application_credential:ListApplicationCredential"
+application_credential_show = "openstackclient.identity.v3.application_credential:ShowApplicationCredential"
+catalog_list = "openstackclient.identity.v3.catalog:ListCatalog"
+catalog_show = "openstackclient.identity.v3.catalog:ShowCatalog"
+consumer_create = "openstackclient.identity.v3.consumer:CreateConsumer"
+consumer_delete = "openstackclient.identity.v3.consumer:DeleteConsumer"
+consumer_list = "openstackclient.identity.v3.consumer:ListConsumer"
+consumer_set = "openstackclient.identity.v3.consumer:SetConsumer"
+consumer_show = "openstackclient.identity.v3.consumer:ShowConsumer"
+credential_create = "openstackclient.identity.v3.credential:CreateCredential"
+credential_delete = "openstackclient.identity.v3.credential:DeleteCredential"
+credential_list = "openstackclient.identity.v3.credential:ListCredential"
+credential_set = "openstackclient.identity.v3.credential:SetCredential"
+credential_show = "openstackclient.identity.v3.credential:ShowCredential"
+domain_create = "openstackclient.identity.v3.domain:CreateDomain"
+domain_delete = "openstackclient.identity.v3.domain:DeleteDomain"
+domain_list = "openstackclient.identity.v3.domain:ListDomain"
+domain_set = "openstackclient.identity.v3.domain:SetDomain"
+domain_show = "openstackclient.identity.v3.domain:ShowDomain"
+ec2_credentials_create = "openstackclient.identity.v3.ec2creds:CreateEC2Creds"
+ec2_credentials_delete = "openstackclient.identity.v3.ec2creds:DeleteEC2Creds"
+ec2_credentials_list = "openstackclient.identity.v3.ec2creds:ListEC2Creds"
+ec2_credentials_show = "openstackclient.identity.v3.ec2creds:ShowEC2Creds"
+endpoint_add_project = "openstackclient.identity.v3.endpoint:AddProjectToEndpoint"
+endpoint_create = "openstackclient.identity.v3.endpoint:CreateEndpoint"
+endpoint_delete = "openstackclient.identity.v3.endpoint:DeleteEndpoint"
+endpoint_list = "openstackclient.identity.v3.endpoint:ListEndpoint"
+endpoint_remove_project = "openstackclient.identity.v3.endpoint:RemoveProjectFromEndpoint"
+endpoint_set = "openstackclient.identity.v3.endpoint:SetEndpoint"
+endpoint_show = "openstackclient.identity.v3.endpoint:ShowEndpoint"
+endpoint_group_add_project = "openstackclient.identity.v3.endpoint_group:AddProjectToEndpointGroup"
+endpoint_group_create = "openstackclient.identity.v3.endpoint_group:CreateEndpointGroup"
+endpoint_group_delete = "openstackclient.identity.v3.endpoint_group:DeleteEndpointGroup"
+endpoint_group_list = "openstackclient.identity.v3.endpoint_group:ListEndpointGroup"
+endpoint_group_remove_project = "openstackclient.identity.v3.endpoint_group:RemoveProjectFromEndpointGroup"
+endpoint_group_set = "openstackclient.identity.v3.endpoint_group:SetEndpointGroup"
+endpoint_group_show = "openstackclient.identity.v3.endpoint_group:ShowEndpointGroup"
+federation_domain_list = "openstackclient.identity.v3.unscoped_saml:ListAccessibleDomains"
+federation_project_list = "openstackclient.identity.v3.unscoped_saml:ListAccessibleProjects"
+federation_protocol_create = "openstackclient.identity.v3.federation_protocol:CreateProtocol"
+federation_protocol_delete = "openstackclient.identity.v3.federation_protocol:DeleteProtocol"
+federation_protocol_list = "openstackclient.identity.v3.federation_protocol:ListProtocols"
+federation_protocol_set = "openstackclient.identity.v3.federation_protocol:SetProtocol"
+federation_protocol_show = "openstackclient.identity.v3.federation_protocol:ShowProtocol"
+group_add_user = "openstackclient.identity.v3.group:AddUserToGroup"
+group_contains_user = "openstackclient.identity.v3.group:CheckUserInGroup"
+group_create = "openstackclient.identity.v3.group:CreateGroup"
+group_delete = "openstackclient.identity.v3.group:DeleteGroup"
+group_list = "openstackclient.identity.v3.group:ListGroup"
+group_remove_user = "openstackclient.identity.v3.group:RemoveUserFromGroup"
+group_set = "openstackclient.identity.v3.group:SetGroup"
+group_show = "openstackclient.identity.v3.group:ShowGroup"
+identity_provider_create = "openstackclient.identity.v3.identity_provider:CreateIdentityProvider"
+identity_provider_delete = "openstackclient.identity.v3.identity_provider:DeleteIdentityProvider"
+identity_provider_list = "openstackclient.identity.v3.identity_provider:ListIdentityProvider"
+identity_provider_set = "openstackclient.identity.v3.identity_provider:SetIdentityProvider"
+identity_provider_show = "openstackclient.identity.v3.identity_provider:ShowIdentityProvider"
+implied_role_create = "openstackclient.identity.v3.implied_role:CreateImpliedRole"
+implied_role_delete = "openstackclient.identity.v3.implied_role:DeleteImpliedRole"
+implied_role_list = "openstackclient.identity.v3.implied_role:ListImpliedRole"
+limit_create = "openstackclient.identity.v3.limit:CreateLimit"
+limit_delete = "openstackclient.identity.v3.limit:DeleteLimit"
+limit_list = "openstackclient.identity.v3.limit:ListLimit"
+limit_set = "openstackclient.identity.v3.limit:SetLimit"
+limit_show = "openstackclient.identity.v3.limit:ShowLimit"
+mapping_create = "openstackclient.identity.v3.mapping:CreateMapping"
+mapping_delete = "openstackclient.identity.v3.mapping:DeleteMapping"
+mapping_list = "openstackclient.identity.v3.mapping:ListMapping"
+mapping_set = "openstackclient.identity.v3.mapping:SetMapping"
+mapping_show = "openstackclient.identity.v3.mapping:ShowMapping"
+policy_create = "openstackclient.identity.v3.policy:CreatePolicy"
+policy_delete = "openstackclient.identity.v3.policy:DeletePolicy"
+policy_list = "openstackclient.identity.v3.policy:ListPolicy"
+policy_set = "openstackclient.identity.v3.policy:SetPolicy"
+policy_show = "openstackclient.identity.v3.policy:ShowPolicy"
+project_create = "openstackclient.identity.v3.project:CreateProject"
+project_delete = "openstackclient.identity.v3.project:DeleteProject"
+project_list = "openstackclient.identity.v3.project:ListProject"
+project_set = "openstackclient.identity.v3.project:SetProject"
+project_show = "openstackclient.identity.v3.project:ShowProject"
+region_create = "openstackclient.identity.v3.region:CreateRegion"
+region_delete = "openstackclient.identity.v3.region:DeleteRegion"
+region_list = "openstackclient.identity.v3.region:ListRegion"
+region_set = "openstackclient.identity.v3.region:SetRegion"
+region_show = "openstackclient.identity.v3.region:ShowRegion"
+registered_limit_create = "openstackclient.identity.v3.registered_limit:CreateRegisteredLimit"
+registered_limit_delete = "openstackclient.identity.v3.registered_limit:DeleteRegisteredLimit"
+registered_limit_list = "openstackclient.identity.v3.registered_limit:ListRegisteredLimit"
+registered_limit_set = "openstackclient.identity.v3.registered_limit:SetRegisteredLimit"
+registered_limit_show = "openstackclient.identity.v3.registered_limit:ShowRegisteredLimit"
+request_token_authorize = "openstackclient.identity.v3.token:AuthorizeRequestToken"
+request_token_create = "openstackclient.identity.v3.token:CreateRequestToken"
+role_add = "openstackclient.identity.v3.role:AddRole"
+role_create = "openstackclient.identity.v3.role:CreateRole"
+role_delete = "openstackclient.identity.v3.role:DeleteRole"
+role_list = "openstackclient.identity.v3.role:ListRole"
+role_remove = "openstackclient.identity.v3.role:RemoveRole"
+role_show = "openstackclient.identity.v3.role:ShowRole"
+role_set = "openstackclient.identity.v3.role:SetRole"
+role_assignment_list = "openstackclient.identity.v3.role_assignment:ListRoleAssignment"
+service_create = "openstackclient.identity.v3.service:CreateService"
+service_delete = "openstackclient.identity.v3.service:DeleteService"
+service_list = "openstackclient.identity.v3.service:ListService"
+service_show = "openstackclient.identity.v3.service:ShowService"
+service_set = "openstackclient.identity.v3.service:SetService"
+service_provider_create = "openstackclient.identity.v3.service_provider:CreateServiceProvider"
+service_provider_delete = "openstackclient.identity.v3.service_provider:DeleteServiceProvider"
+service_provider_list = "openstackclient.identity.v3.service_provider:ListServiceProvider"
+service_provider_set = "openstackclient.identity.v3.service_provider:SetServiceProvider"
+service_provider_show = "openstackclient.identity.v3.service_provider:ShowServiceProvider"
+token_issue = "openstackclient.identity.v3.token:IssueToken"
+token_revoke = "openstackclient.identity.v3.token:RevokeToken"
+trust_create = "openstackclient.identity.v3.trust:CreateTrust"
+trust_delete = "openstackclient.identity.v3.trust:DeleteTrust"
+trust_list = "openstackclient.identity.v3.trust:ListTrust"
+trust_show = "openstackclient.identity.v3.trust:ShowTrust"
+user_create = "openstackclient.identity.v3.user:CreateUser"
+user_delete = "openstackclient.identity.v3.user:DeleteUser"
+user_list = "openstackclient.identity.v3.user:ListUser"
+user_set = "openstackclient.identity.v3.user:SetUser"
+user_password_set = "openstackclient.identity.v3.user:SetPasswordUser"
+user_show = "openstackclient.identity.v3.user:ShowUser"
+
+[project.entry-points."openstack.image.v1"]
+image_create = "openstackclient.image.v1.image:CreateImage"
+image_delete = "openstackclient.image.v1.image:DeleteImage"
+image_list = "openstackclient.image.v1.image:ListImage"
+image_save = "openstackclient.image.v1.image:SaveImage"
+image_set = "openstackclient.image.v1.image:SetImage"
+image_show = "openstackclient.image.v1.image:ShowImage"
+
+[project.entry-points."openstack.image.v2"]
+image_add_project = "openstackclient.image.v2.image:AddProjectToImage"
+image_create = "openstackclient.image.v2.image:CreateImage"
+image_delete = "openstackclient.image.v2.image:DeleteImage"
+image_list = "openstackclient.image.v2.image:ListImage"
+image_member_list = "openstackclient.image.v2.image:ListImageProjects"
+image_remove_project = "openstackclient.image.v2.image:RemoveProjectImage"
+image_member_get = "openstackclient.image.v2.image:ShowProjectImage"
+image_save = "openstackclient.image.v2.image:SaveImage"
+image_show = "openstackclient.image.v2.image:ShowImage"
+image_set = "openstackclient.image.v2.image:SetImage"
+image_unset = "openstackclient.image.v2.image:UnsetImage"
+image_stage = "openstackclient.image.v2.image:StageImage"
+image_task_show = "openstackclient.image.v2.task:ShowTask"
+image_task_list = "openstackclient.image.v2.task:ListTask"
+image_import_info = "openstackclient.image.v2.info:ImportInfo"
+image_import = "openstackclient.image.v2.image:ImportImage"
+image_stores_list = "openstackclient.image.v2.image:StoresInfo"
+image_metadef_namespace_create = "openstackclient.image.v2.metadef_namespaces:CreateMetadefNamespace"
+image_metadef_namespace_delete = "openstackclient.image.v2.metadef_namespaces:DeleteMetadefNamespace"
+image_metadef_namespace_list = "openstackclient.image.v2.metadef_namespaces:ListMetadefNamespace"
+image_metadef_namespace_set = "openstackclient.image.v2.metadef_namespaces:SetMetadefNamespace"
+image_metadef_namespace_show = "openstackclient.image.v2.metadef_namespaces:ShowMetadefNamespace"
+image_metadef_object_create = "openstackclient.image.v2.metadef_objects:CreateMetadefObjects"
+image_metadef_object_show = "openstackclient.image.v2.metadef_objects:ShowMetadefObjects"
+image_metadef_object_list = "openstackclient.image.v2.metadef_objects:ListMetadefObjects"
+image_metadef_object_delete = "openstackclient.image.v2.metadef_objects:DeleteMetadefObject"
+image_metadef_object_update = "openstackclient.image.v2.metadef_objects:SetMetadefObject"
+image_metadef_object_property_show = "openstackclient.image.v2.metadef_objects:ShowMetadefObjectProperty"
+image_metadef_property_create = "openstackclient.image.v2.metadef_properties:CreateMetadefProperty"
+image_metadef_property_delete = "openstackclient.image.v2.metadef_properties:DeleteMetadefProperty"
+image_metadef_property_list = "openstackclient.image.v2.metadef_properties:ListMetadefProperties"
+image_metadef_property_set = "openstackclient.image.v2.metadef_properties:SetMetadefProperty"
+image_metadef_property_show = "openstackclient.image.v2.metadef_properties:ShowMetadefProperty"
+image_metadef_resource_type_list = "openstackclient.image.v2.metadef_resource_types:ListMetadefResourceTypes"
+image_metadef_resource_type_association_create = "openstackclient.image.v2.metadef_resource_type_association:CreateMetadefResourceTypeAssociation"
+image_metadef_resource_type_association_delete = "openstackclient.image.v2.metadef_resource_type_association:DeleteMetadefResourceTypeAssociation"
+image_metadef_resource_type_association_list = "openstackclient.image.v2.metadef_resource_type_association:ListMetadefResourceTypeAssociations"
+cached_image_list = "openstackclient.image.v2.cache:ListCachedImage"
+cached_image_queue = "openstackclient.image.v2.cache:QueueCachedImage"
+cached_image_delete = "openstackclient.image.v2.cache:DeleteCachedImage"
+cached_image_clear = "openstackclient.image.v2.cache:ClearCachedImage"
+
+[project.entry-points."openstack.network.v2"]
+address_group_create = "openstackclient.network.v2.address_group:CreateAddressGroup"
+address_group_delete = "openstackclient.network.v2.address_group:DeleteAddressGroup"
+address_group_list = "openstackclient.network.v2.address_group:ListAddressGroup"
+address_group_set = "openstackclient.network.v2.address_group:SetAddressGroup"
+address_group_show = "openstackclient.network.v2.address_group:ShowAddressGroup"
+address_group_unset = "openstackclient.network.v2.address_group:UnsetAddressGroup"
+address_scope_create = "openstackclient.network.v2.address_scope:CreateAddressScope"
+address_scope_delete = "openstackclient.network.v2.address_scope:DeleteAddressScope"
+address_scope_list = "openstackclient.network.v2.address_scope:ListAddressScope"
+address_scope_set = "openstackclient.network.v2.address_scope:SetAddressScope"
+address_scope_show = "openstackclient.network.v2.address_scope:ShowAddressScope"
+floating_ip_create = "openstackclient.network.v2.floating_ip:CreateFloatingIP"
+floating_ip_delete = "openstackclient.network.v2.floating_ip:DeleteFloatingIP"
+floating_ip_list = "openstackclient.network.v2.floating_ip:ListFloatingIP"
+floating_ip_set = "openstackclient.network.v2.floating_ip:SetFloatingIP"
+floating_ip_show = "openstackclient.network.v2.floating_ip:ShowFloatingIP"
+floating_ip_unset = "openstackclient.network.v2.floating_ip:UnsetFloatingIP"
+floating_ip_pool_list = "openstackclient.network.v2.floating_ip_pool:ListFloatingIPPool"
+floating_ip_port_forwarding_create = "openstackclient.network.v2.floating_ip_port_forwarding:CreateFloatingIPPortForwarding"
+floating_ip_port_forwarding_delete = "openstackclient.network.v2.floating_ip_port_forwarding:DeleteFloatingIPPortForwarding"
+floating_ip_port_forwarding_list = "openstackclient.network.v2.floating_ip_port_forwarding:ListFloatingIPPortForwarding"
+floating_ip_port_forwarding_set = "openstackclient.network.v2.floating_ip_port_forwarding:SetFloatingIPPortForwarding"
+floating_ip_port_forwarding_show = "openstackclient.network.v2.floating_ip_port_forwarding:ShowFloatingIPPortForwarding"
+ip_availability_list = "openstackclient.network.v2.ip_availability:ListIPAvailability"
+ip_availability_show = "openstackclient.network.v2.ip_availability:ShowIPAvailability"
+local_ip_create = "openstackclient.network.v2.local_ip:CreateLocalIP"
+local_ip_delete = "openstackclient.network.v2.local_ip:DeleteLocalIP"
+local_ip_list = "openstackclient.network.v2.local_ip:ListLocalIP"
+local_ip_set = "openstackclient.network.v2.local_ip:SetLocalIP"
+local_ip_show = "openstackclient.network.v2.local_ip:ShowLocalIP"
+local_ip_association_create = "openstackclient.network.v2.local_ip_association:CreateLocalIPAssociation"
+local_ip_association_delete = "openstackclient.network.v2.local_ip_association:DeleteLocalIPAssociation"
+local_ip_association_list = "openstackclient.network.v2.local_ip_association:ListLocalIPAssociation"
+network_agent_add_network = "openstackclient.network.v2.network_agent:AddNetworkToAgent"
+network_agent_add_router = "openstackclient.network.v2.network_agent:AddRouterToAgent"
+network_agent_delete = "openstackclient.network.v2.network_agent:DeleteNetworkAgent"
+network_agent_list = "openstackclient.network.v2.network_agent:ListNetworkAgent"
+network_agent_remove_network = "openstackclient.network.v2.network_agent:RemoveNetworkFromAgent"
+network_agent_remove_router = "openstackclient.network.v2.network_agent:RemoveRouterFromAgent"
+network_agent_set = "openstackclient.network.v2.network_agent:SetNetworkAgent"
+network_agent_show = "openstackclient.network.v2.network_agent:ShowNetworkAgent"
+network_auto_allocated_topology_create = "openstackclient.network.v2.network_auto_allocated_topology:CreateAutoAllocatedTopology"
+network_auto_allocated_topology_delete = "openstackclient.network.v2.network_auto_allocated_topology:DeleteAutoAllocatedTopology"
+network_flavor_add_profile = "openstackclient.network.v2.network_flavor:AddNetworkFlavorToProfile"
+network_flavor_create = "openstackclient.network.v2.network_flavor:CreateNetworkFlavor"
+network_flavor_delete = "openstackclient.network.v2.network_flavor:DeleteNetworkFlavor"
+network_flavor_list = "openstackclient.network.v2.network_flavor:ListNetworkFlavor"
+network_flavor_remove_profile = "openstackclient.network.v2.network_flavor:RemoveNetworkFlavorFromProfile"
+network_flavor_set = "openstackclient.network.v2.network_flavor:SetNetworkFlavor"
+network_flavor_show = "openstackclient.network.v2.network_flavor:ShowNetworkFlavor"
+network_flavor_profile_create = "openstackclient.network.v2.network_flavor_profile:CreateNetworkFlavorProfile"
+network_flavor_profile_delete = "openstackclient.network.v2.network_flavor_profile:DeleteNetworkFlavorProfile"
+network_flavor_profile_list = "openstackclient.network.v2.network_flavor_profile:ListNetworkFlavorProfile"
+network_flavor_profile_set = "openstackclient.network.v2.network_flavor_profile:SetNetworkFlavorProfile"
+network_flavor_profile_show = "openstackclient.network.v2.network_flavor_profile:ShowNetworkFlavorProfile"
+network_create = "openstackclient.network.v2.network:CreateNetwork"
+network_delete = "openstackclient.network.v2.network:DeleteNetwork"
+network_list = "openstackclient.network.v2.network:ListNetwork"
+network_set = "openstackclient.network.v2.network:SetNetwork"
+network_show = "openstackclient.network.v2.network:ShowNetwork"
+network_unset = "openstackclient.network.v2.network:UnsetNetwork"
+network_l3_conntrack_helper_create = "openstackclient.network.v2.l3_conntrack_helper:CreateConntrackHelper"
+network_l3_conntrack_helper_delete = "openstackclient.network.v2.l3_conntrack_helper:DeleteConntrackHelper"
+network_l3_conntrack_helper_list = "openstackclient.network.v2.l3_conntrack_helper:ListConntrackHelper"
+network_l3_conntrack_helper_set = "openstackclient.network.v2.l3_conntrack_helper:SetConntrackHelper"
+network_l3_conntrack_helper_show = "openstackclient.network.v2.l3_conntrack_helper:ShowConntrackHelper"
+network_meter_create = "openstackclient.network.v2.network_meter:CreateMeter"
+network_meter_delete = "openstackclient.network.v2.network_meter:DeleteMeter"
+network_meter_list = "openstackclient.network.v2.network_meter:ListMeter"
+network_meter_show = "openstackclient.network.v2.network_meter:ShowMeter"
+network_meter_rule_create = "openstackclient.network.v2.network_meter_rule:CreateMeterRule"
+network_meter_rule_delete = "openstackclient.network.v2.network_meter_rule:DeleteMeterRule"
+network_meter_rule_list = "openstackclient.network.v2.network_meter_rule:ListMeterRule"
+network_meter_rule_show = "openstackclient.network.v2.network_meter_rule:ShowMeterRule"
+network_qos_policy_create = "openstackclient.network.v2.network_qos_policy:CreateNetworkQosPolicy"
+network_qos_policy_delete = "openstackclient.network.v2.network_qos_policy:DeleteNetworkQosPolicy"
+network_qos_policy_list = "openstackclient.network.v2.network_qos_policy:ListNetworkQosPolicy"
+network_qos_policy_set = "openstackclient.network.v2.network_qos_policy:SetNetworkQosPolicy"
+network_qos_policy_show = "openstackclient.network.v2.network_qos_policy:ShowNetworkQosPolicy"
+network_qos_rule_create = "openstackclient.network.v2.network_qos_rule:CreateNetworkQosRule"
+network_qos_rule_delete = "openstackclient.network.v2.network_qos_rule:DeleteNetworkQosRule"
+network_qos_rule_list = "openstackclient.network.v2.network_qos_rule:ListNetworkQosRule"
+network_qos_rule_set = "openstackclient.network.v2.network_qos_rule:SetNetworkQosRule"
+network_qos_rule_show = "openstackclient.network.v2.network_qos_rule:ShowNetworkQosRule"
+network_qos_rule_type_list = "openstackclient.network.v2.network_qos_rule_type:ListNetworkQosRuleType"
+network_qos_rule_type_show = "openstackclient.network.v2.network_qos_rule_type:ShowNetworkQosRuleType"
+network_rbac_create = "openstackclient.network.v2.network_rbac:CreateNetworkRBAC"
+network_rbac_delete = "openstackclient.network.v2.network_rbac:DeleteNetworkRBAC"
+network_rbac_list = "openstackclient.network.v2.network_rbac:ListNetworkRBAC"
+network_rbac_set = "openstackclient.network.v2.network_rbac:SetNetworkRBAC"
+network_rbac_show = "openstackclient.network.v2.network_rbac:ShowNetworkRBAC"
+network_segment_create = "openstackclient.network.v2.network_segment:CreateNetworkSegment"
+network_segment_delete = "openstackclient.network.v2.network_segment:DeleteNetworkSegment"
+network_segment_list = "openstackclient.network.v2.network_segment:ListNetworkSegment"
+network_segment_set = "openstackclient.network.v2.network_segment:SetNetworkSegment"
+network_segment_show = "openstackclient.network.v2.network_segment:ShowNetworkSegment"
+network_segment_range_create = "openstackclient.network.v2.network_segment_range:CreateNetworkSegmentRange"
+network_segment_range_delete = "openstackclient.network.v2.network_segment_range:DeleteNetworkSegmentRange"
+network_segment_range_list = "openstackclient.network.v2.network_segment_range:ListNetworkSegmentRange"
+network_segment_range_set = "openstackclient.network.v2.network_segment_range:SetNetworkSegmentRange"
+network_segment_range_show = "openstackclient.network.v2.network_segment_range:ShowNetworkSegmentRange"
+network_service_provider_list = "openstackclient.network.v2.network_service_provider:ListNetworkServiceProvider"
+network_subport_list = "openstackclient.network.v2.network_trunk:ListNetworkSubport"
+network_trunk_create = "openstackclient.network.v2.network_trunk:CreateNetworkTrunk"
+network_trunk_delete = "openstackclient.network.v2.network_trunk:DeleteNetworkTrunk"
+network_trunk_list = "openstackclient.network.v2.network_trunk:ListNetworkTrunk"
+network_trunk_set = "openstackclient.network.v2.network_trunk:SetNetworkTrunk"
+network_trunk_show = "openstackclient.network.v2.network_trunk:ShowNetworkTrunk"
+network_trunk_unset = "openstackclient.network.v2.network_trunk:UnsetNetworkTrunk"
+port_create = "openstackclient.network.v2.port:CreatePort"
+port_delete = "openstackclient.network.v2.port:DeletePort"
+port_list = "openstackclient.network.v2.port:ListPort"
+port_set = "openstackclient.network.v2.port:SetPort"
+port_show = "openstackclient.network.v2.port:ShowPort"
+port_unset = "openstackclient.network.v2.port:UnsetPort"
+router_add_gateway = "openstackclient.network.v2.router:AddGatewayToRouter"
+router_add_port = "openstackclient.network.v2.router:AddPortToRouter"
+router_add_route = "openstackclient.network.v2.router:AddExtraRoutesToRouter"
+router_add_subnet = "openstackclient.network.v2.router:AddSubnetToRouter"
+router_create = "openstackclient.network.v2.router:CreateRouter"
+router_delete = "openstackclient.network.v2.router:DeleteRouter"
+router_list = "openstackclient.network.v2.router:ListRouter"
+router_remove_gateway = "openstackclient.network.v2.router:RemoveGatewayFromRouter"
+router_remove_port = "openstackclient.network.v2.router:RemovePortFromRouter"
+router_remove_route = "openstackclient.network.v2.router:RemoveExtraRoutesFromRouter"
+router_remove_subnet = "openstackclient.network.v2.router:RemoveSubnetFromRouter"
+router_set = "openstackclient.network.v2.router:SetRouter"
+router_show = "openstackclient.network.v2.router:ShowRouter"
+router_unset = "openstackclient.network.v2.router:UnsetRouter"
+router_ndp_proxy_create = "openstackclient.network.v2.ndp_proxy:CreateNDPProxy"
+router_ndp_proxy_delete = "openstackclient.network.v2.ndp_proxy:DeleteNDPProxy"
+router_ndp_proxy_list = "openstackclient.network.v2.ndp_proxy:ListNDPProxy"
+router_ndp_proxy_set = "openstackclient.network.v2.ndp_proxy:SetNDPProxy"
+router_ndp_proxy_show = "openstackclient.network.v2.ndp_proxy:ShowNDPProxy"
+security_group_create = "openstackclient.network.v2.security_group:CreateSecurityGroup"
+security_group_delete = "openstackclient.network.v2.security_group:DeleteSecurityGroup"
+security_group_list = "openstackclient.network.v2.security_group:ListSecurityGroup"
+security_group_set = "openstackclient.network.v2.security_group:SetSecurityGroup"
+security_group_show = "openstackclient.network.v2.security_group:ShowSecurityGroup"
+security_group_unset = "openstackclient.network.v2.security_group:UnsetSecurityGroup"
+security_group_rule_create = "openstackclient.network.v2.security_group_rule:CreateSecurityGroupRule"
+security_group_rule_delete = "openstackclient.network.v2.security_group_rule:DeleteSecurityGroupRule"
+security_group_rule_list = "openstackclient.network.v2.security_group_rule:ListSecurityGroupRule"
+security_group_rule_show = "openstackclient.network.v2.security_group_rule:ShowSecurityGroupRule"
+default_security_group_rule_create = "openstackclient.network.v2.default_security_group_rule:CreateDefaultSecurityGroupRule"
+default_security_group_rule_delete = "openstackclient.network.v2.default_security_group_rule:DeleteDefaultSecurityGroupRule"
+default_security_group_rule_list = "openstackclient.network.v2.default_security_group_rule:ListDefaultSecurityGroupRule"
+default_security_group_rule_show = "openstackclient.network.v2.default_security_group_rule:ShowDefaultSecurityGroupRule"
+subnet_create = "openstackclient.network.v2.subnet:CreateSubnet"
+subnet_delete = "openstackclient.network.v2.subnet:DeleteSubnet"
+subnet_list = "openstackclient.network.v2.subnet:ListSubnet"
+subnet_set = "openstackclient.network.v2.subnet:SetSubnet"
+subnet_show = "openstackclient.network.v2.subnet:ShowSubnet"
+subnet_unset = "openstackclient.network.v2.subnet:UnsetSubnet"
+subnet_pool_create = "openstackclient.network.v2.subnet_pool:CreateSubnetPool"
+subnet_pool_delete = "openstackclient.network.v2.subnet_pool:DeleteSubnetPool"
+subnet_pool_list = "openstackclient.network.v2.subnet_pool:ListSubnetPool"
+subnet_pool_set = "openstackclient.network.v2.subnet_pool:SetSubnetPool"
+subnet_pool_show = "openstackclient.network.v2.subnet_pool:ShowSubnetPool"
+subnet_pool_unset = "openstackclient.network.v2.subnet_pool:UnsetSubnetPool"
+
+[project.entry-points."openstack.object_store.v1"]
+object_store_account_set = "openstackclient.object.v1.account:SetAccount"
+object_store_account_show = "openstackclient.object.v1.account:ShowAccount"
+object_store_account_unset = "openstackclient.object.v1.account:UnsetAccount"
+container_create = "openstackclient.object.v1.container:CreateContainer"
+container_delete = "openstackclient.object.v1.container:DeleteContainer"
+container_list = "openstackclient.object.v1.container:ListContainer"
+container_save = "openstackclient.object.v1.container:SaveContainer"
+container_set = "openstackclient.object.v1.container:SetContainer"
+container_show = "openstackclient.object.v1.container:ShowContainer"
+container_unset = "openstackclient.object.v1.container:UnsetContainer"
+object_create = "openstackclient.object.v1.object:CreateObject"
+object_delete = "openstackclient.object.v1.object:DeleteObject"
+object_list = "openstackclient.object.v1.object:ListObject"
+object_save = "openstackclient.object.v1.object:SaveObject"
+object_set = "openstackclient.object.v1.object:SetObject"
+object_show = "openstackclient.object.v1.object:ShowObject"
+object_unset = "openstackclient.object.v1.object:UnsetObject"
+
+[project.entry-points."openstack.volume.v2"]
+consistency_group_add_volume = "openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup"
+consistency_group_create = "openstackclient.volume.v2.consistency_group:CreateConsistencyGroup"
+consistency_group_delete = "openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup"
+consistency_group_list = "openstackclient.volume.v2.consistency_group:ListConsistencyGroup"
+consistency_group_remove_volume = "openstackclient.volume.v2.consistency_group:RemoveVolumeFromConsistencyGroup"
+consistency_group_set = "openstackclient.volume.v2.consistency_group:SetConsistencyGroup"
+consistency_group_show = "openstackclient.volume.v2.consistency_group:ShowConsistencyGroup"
+consistency_group_snapshot_create = "openstackclient.volume.v2.consistency_group_snapshot:CreateConsistencyGroupSnapshot"
+consistency_group_snapshot_delete = "openstackclient.volume.v2.consistency_group_snapshot:DeleteConsistencyGroupSnapshot"
+consistency_group_snapshot_list = "openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot"
+consistency_group_snapshot_show = "openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot"
+volume_create = "openstackclient.volume.v2.volume:CreateVolume"
+volume_delete = "openstackclient.volume.v2.volume:DeleteVolume"
+volume_list = "openstackclient.volume.v2.volume:ListVolume"
+volume_migrate = "openstackclient.volume.v2.volume:MigrateVolume"
+volume_set = "openstackclient.volume.v2.volume:SetVolume"
+volume_show = "openstackclient.volume.v2.volume:ShowVolume"
+volume_unset = "openstackclient.volume.v2.volume:UnsetVolume"
+volume_backup_create = "openstackclient.volume.v2.volume_backup:CreateVolumeBackup"
+volume_backup_delete = "openstackclient.volume.v2.volume_backup:DeleteVolumeBackup"
+volume_backup_list = "openstackclient.volume.v2.volume_backup:ListVolumeBackup"
+volume_backup_restore = "openstackclient.volume.v2.volume_backup:RestoreVolumeBackup"
+volume_backup_set = "openstackclient.volume.v2.volume_backup:SetVolumeBackup"
+volume_backup_show = "openstackclient.volume.v2.volume_backup:ShowVolumeBackup"
+volume_backup_record_export = "openstackclient.volume.v2.backup_record:ExportBackupRecord"
+volume_backup_record_import = "openstackclient.volume.v2.backup_record:ImportBackupRecord"
+volume_backend_capability_show = "openstackclient.volume.v2.volume_backend:ShowCapability"
+volume_backend_pool_list = "openstackclient.volume.v2.volume_backend:ListPool"
+volume_host_failover = "openstackclient.volume.v2.volume_host:FailoverVolumeHost"
+volume_host_set = "openstackclient.volume.v2.volume_host:SetVolumeHost"
+volume_snapshot_create = "openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot"
+volume_snapshot_delete = "openstackclient.volume.v2.volume_snapshot:DeleteVolumeSnapshot"
+volume_snapshot_list = "openstackclient.volume.v2.volume_snapshot:ListVolumeSnapshot"
+volume_snapshot_set = "openstackclient.volume.v2.volume_snapshot:SetVolumeSnapshot"
+volume_snapshot_show = "openstackclient.volume.v2.volume_snapshot:ShowVolumeSnapshot"
+volume_snapshot_unset = "openstackclient.volume.v2.volume_snapshot:UnsetVolumeSnapshot"
+volume_type_create = "openstackclient.volume.v2.volume_type:CreateVolumeType"
+volume_type_delete = "openstackclient.volume.v2.volume_type:DeleteVolumeType"
+volume_type_list = "openstackclient.volume.v2.volume_type:ListVolumeType"
+volume_type_set = "openstackclient.volume.v2.volume_type:SetVolumeType"
+volume_type_show = "openstackclient.volume.v2.volume_type:ShowVolumeType"
+volume_type_unset = "openstackclient.volume.v2.volume_type:UnsetVolumeType"
+volume_qos_associate = "openstackclient.volume.v2.qos_specs:AssociateQos"
+volume_qos_create = "openstackclient.volume.v2.qos_specs:CreateQos"
+volume_qos_delete = "openstackclient.volume.v2.qos_specs:DeleteQos"
+volume_qos_disassociate = "openstackclient.volume.v2.qos_specs:DisassociateQos"
+volume_qos_list = "openstackclient.volume.v2.qos_specs:ListQos"
+volume_qos_set = "openstackclient.volume.v2.qos_specs:SetQos"
+volume_qos_show = "openstackclient.volume.v2.qos_specs:ShowQos"
+volume_qos_unset = "openstackclient.volume.v2.qos_specs:UnsetQos"
+volume_service_list = "openstackclient.volume.v2.service:ListService"
+volume_service_set = "openstackclient.volume.v2.service:SetService"
+volume_transfer_request_accept = "openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest"
+volume_transfer_request_create = "openstackclient.volume.v2.volume_transfer_request:CreateTransferRequest"
+volume_transfer_request_delete = "openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest"
+volume_transfer_request_list = "openstackclient.volume.v2.volume_transfer_request:ListTransferRequest"
+volume_transfer_request_show = "openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest"
+
+[project.entry-points."openstack.volume.v3"]
+block_storage_log_level_list = "openstackclient.volume.v3.block_storage_log_level:BlockStorageLogLevelList"
+block_storage_log_level_set = "openstackclient.volume.v3.block_storage_log_level:BlockStorageLogLevelSet"
+block_storage_cleanup = "openstackclient.volume.v3.block_storage_cleanup:BlockStorageCleanup"
+block_storage_volume_manageable_list = "openstackclient.volume.v3.block_storage_manage:BlockStorageManageVolumes"
+block_storage_snapshot_manageable_list = "openstackclient.volume.v3.block_storage_manage:BlockStorageManageSnapshots"
+consistency_group_add_volume = "openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup"
+consistency_group_create = "openstackclient.volume.v2.consistency_group:CreateConsistencyGroup"
+consistency_group_delete = "openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup"
+consistency_group_list = "openstackclient.volume.v2.consistency_group:ListConsistencyGroup"
+consistency_group_remove_volume = "openstackclient.volume.v2.consistency_group:RemoveVolumeFromConsistencyGroup"
+consistency_group_set = "openstackclient.volume.v2.consistency_group:SetConsistencyGroup"
+consistency_group_show = "openstackclient.volume.v2.consistency_group:ShowConsistencyGroup"
+consistency_group_snapshot_create = "openstackclient.volume.v2.consistency_group_snapshot:CreateConsistencyGroupSnapshot"
+consistency_group_snapshot_delete = "openstackclient.volume.v2.consistency_group_snapshot:DeleteConsistencyGroupSnapshot"
+consistency_group_snapshot_list = "openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot"
+consistency_group_snapshot_show = "openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot"
+volume_create = "openstackclient.volume.v3.volume:CreateVolume"
+volume_delete = "openstackclient.volume.v3.volume:DeleteVolume"
+volume_list = "openstackclient.volume.v3.volume:ListVolume"
+volume_migrate = "openstackclient.volume.v3.volume:MigrateVolume"
+volume_set = "openstackclient.volume.v3.volume:SetVolume"
+volume_show = "openstackclient.volume.v3.volume:ShowVolume"
+volume_unset = "openstackclient.volume.v3.volume:UnsetVolume"
+volume_attachment_create = "openstackclient.volume.v3.volume_attachment:CreateVolumeAttachment"
+volume_attachment_delete = "openstackclient.volume.v3.volume_attachment:DeleteVolumeAttachment"
+volume_attachment_list = "openstackclient.volume.v3.volume_attachment:ListVolumeAttachment"
+volume_attachment_complete = "openstackclient.volume.v3.volume_attachment:CompleteVolumeAttachment"
+volume_attachment_set = "openstackclient.volume.v3.volume_attachment:SetVolumeAttachment"
+volume_attachment_show = "openstackclient.volume.v3.volume_attachment:ShowVolumeAttachment"
+volume_backup_create = "openstackclient.volume.v3.volume_backup:CreateVolumeBackup"
+volume_backup_delete = "openstackclient.volume.v3.volume_backup:DeleteVolumeBackup"
+volume_backup_list = "openstackclient.volume.v3.volume_backup:ListVolumeBackup"
+volume_backup_restore = "openstackclient.volume.v3.volume_backup:RestoreVolumeBackup"
+volume_backup_set = "openstackclient.volume.v3.volume_backup:SetVolumeBackup"
+volume_backup_unset = "openstackclient.volume.v3.volume_backup:UnsetVolumeBackup"
+volume_backup_show = "openstackclient.volume.v3.volume_backup:ShowVolumeBackup"
+volume_backend_capability_show = "openstackclient.volume.v2.volume_backend:ShowCapability"
+volume_backend_pool_list = "openstackclient.volume.v2.volume_backend:ListPool"
+volume_backup_record_export = "openstackclient.volume.v2.backup_record:ExportBackupRecord"
+volume_backup_record_import = "openstackclient.volume.v2.backup_record:ImportBackupRecord"
+volume_group_create = "openstackclient.volume.v3.volume_group:CreateVolumeGroup"
+volume_group_delete = "openstackclient.volume.v3.volume_group:DeleteVolumeGroup"
+volume_group_list = "openstackclient.volume.v3.volume_group:ListVolumeGroup"
+volume_group_failover = "openstackclient.volume.v3.volume_group:FailoverVolumeGroup"
+volume_group_set = "openstackclient.volume.v3.volume_group:SetVolumeGroup"
+volume_group_show = "openstackclient.volume.v3.volume_group:ShowVolumeGroup"
+volume_group_snapshot_create = "openstackclient.volume.v3.volume_group_snapshot:CreateVolumeGroupSnapshot"
+volume_group_snapshot_delete = "openstackclient.volume.v3.volume_group_snapshot:DeleteVolumeGroupSnapshot"
+volume_group_snapshot_list = "openstackclient.volume.v3.volume_group_snapshot:ListVolumeGroupSnapshot"
+volume_group_snapshot_show = "openstackclient.volume.v3.volume_group_snapshot:ShowVolumeGroupSnapshot"
+volume_group_type_create = "openstackclient.volume.v3.volume_group_type:CreateVolumeGroupType"
+volume_group_type_delete = "openstackclient.volume.v3.volume_group_type:DeleteVolumeGroupType"
+volume_group_type_list = "openstackclient.volume.v3.volume_group_type:ListVolumeGroupType"
+volume_group_type_set = "openstackclient.volume.v3.volume_group_type:SetVolumeGroupType"
+volume_group_type_show = "openstackclient.volume.v3.volume_group_type:ShowVolumeGroupType"
+volume_host_set = "openstackclient.volume.v2.volume_host:SetVolumeHost"
+volume_message_delete = "openstackclient.volume.v3.volume_message:DeleteMessage"
+volume_message_list = "openstackclient.volume.v3.volume_message:ListMessages"
+volume_message_show = "openstackclient.volume.v3.volume_message:ShowMessage"
+block_storage_cluster_list = "openstackclient.volume.v3.block_storage_cluster:ListBlockStorageCluster"
+block_storage_cluster_set = "openstackclient.volume.v3.block_storage_cluster:SetBlockStorageCluster"
+block_storage_cluster_show = "openstackclient.volume.v3.block_storage_cluster:ShowBlockStorageCluster"
+block_storage_resource_filter_list = "openstackclient.volume.v3.block_storage_resource_filter:ListBlockStorageResourceFilter"
+block_storage_resource_filter_show = "openstackclient.volume.v3.block_storage_resource_filter:ShowBlockStorageResourceFilter"
+volume_snapshot_create = "openstackclient.volume.v3.volume_snapshot:CreateVolumeSnapshot"
+volume_snapshot_delete = "openstackclient.volume.v3.volume_snapshot:DeleteVolumeSnapshot"
+volume_snapshot_list = "openstackclient.volume.v3.volume_snapshot:ListVolumeSnapshot"
+volume_snapshot_set = "openstackclient.volume.v3.volume_snapshot:SetVolumeSnapshot"
+volume_snapshot_show = "openstackclient.volume.v3.volume_snapshot:ShowVolumeSnapshot"
+volume_snapshot_unset = "openstackclient.volume.v3.volume_snapshot:UnsetVolumeSnapshot"
+volume_type_create = "openstackclient.volume.v3.volume_type:CreateVolumeType"
+volume_type_delete = "openstackclient.volume.v3.volume_type:DeleteVolumeType"
+volume_type_list = "openstackclient.volume.v3.volume_type:ListVolumeType"
+volume_type_set = "openstackclient.volume.v3.volume_type:SetVolumeType"
+volume_type_show = "openstackclient.volume.v3.volume_type:ShowVolumeType"
+volume_type_unset = "openstackclient.volume.v3.volume_type:UnsetVolumeType"
+volume_qos_associate = "openstackclient.volume.v2.qos_specs:AssociateQos"
+volume_qos_create = "openstackclient.volume.v2.qos_specs:CreateQos"
+volume_qos_delete = "openstackclient.volume.v2.qos_specs:DeleteQos"
+volume_qos_disassociate = "openstackclient.volume.v2.qos_specs:DisassociateQos"
+volume_qos_list = "openstackclient.volume.v2.qos_specs:ListQos"
+volume_qos_set = "openstackclient.volume.v2.qos_specs:SetQos"
+volume_qos_show = "openstackclient.volume.v2.qos_specs:ShowQos"
+volume_qos_unset = "openstackclient.volume.v2.qos_specs:UnsetQos"
+volume_service_list = "openstackclient.volume.v3.service:ListService"
+volume_service_set = "openstackclient.volume.v3.service:SetService"
+volume_transfer_request_accept = "openstackclient.volume.v3.volume_transfer_request:AcceptTransferRequest"
+volume_transfer_request_create = "openstackclient.volume.v3.volume_transfer_request:CreateTransferRequest"
+volume_transfer_request_delete = "openstackclient.volume.v3.volume_transfer_request:DeleteTransferRequest"
+volume_transfer_request_list = "openstackclient.volume.v3.volume_transfer_request:ListTransferRequest"
+volume_transfer_request_show = "openstackclient.volume.v3.volume_transfer_request:ShowTransferRequest"
+volume_summary = "openstackclient.volume.v3.volume:VolumeSummary"
+volume_revert = "openstackclient.volume.v3.volume:VolumeRevertToSnapshot"
+
+[tool.setuptools]
+packages = [
+    "openstackclient"
+]
+
+[tool.mypy]
+python_version = "3.10"
+show_column_numbers = true
+show_error_context = true
+ignore_missing_imports = true
+follow_imports = "normal"
+incremental = true
+check_untyped_defs = true
+warn_unused_ignores = true
+# keep this in-sync with 'mypy.exclude' in '.pre-commit-config.yaml'
+exclude = '''
+(?x)(
+    doc
+    | examples
+    | releasenotes
+  )
+'''
+
+[[tool.mypy.overrides]]
+module = ["openstackclient.tests.unit.*"]
+ignore_errors = true
+
 [tool.ruff]
 line-length = 79
 
diff -pruN 7.4.0-3/python_openstackclient.egg-info/PKG-INFO 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/PKG-INFO
--- 7.4.0-3/python_openstackclient.egg-info/PKG-INFO	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/PKG-INFO	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1,264 @@
+Metadata-Version: 2.2
+Name: python-openstackclient
+Version: 8.1.1.dev14
+Summary: OpenStack Command-line Client
+Author-email: OpenStack <openstack-discuss@lists.openstack.org>
+License: Apache-2.0
+Project-URL: Homepage, https://docs.openstack.org/python-openstackclient/
+Project-URL: Repository, https://opendev.org/openstack/python-openstackclient/
+Classifier: Environment :: OpenStack
+Classifier: Intended Audience :: Information Technology
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Requires-Python: >=3.10
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+Requires-Dist: pbr!=2.1.0,>=2.0.0
+Requires-Dist: cryptography>=2.7
+Requires-Dist: cliff>=4.8.0
+Requires-Dist: iso8601>=0.1.11
+Requires-Dist: openstacksdk>=4.5.0
+Requires-Dist: osc-lib>=2.3.0
+Requires-Dist: oslo.i18n>=3.15.3
+Requires-Dist: python-keystoneclient>=3.22.0
+Requires-Dist: python-cinderclient>=3.3.0
+Requires-Dist: requests>=2.27.0
+Requires-Dist: stevedore>=2.0.1
+Dynamic: requires-dist
+
+===============
+OpenStackClient
+===============
+
+.. image:: https://img.shields.io/pypi/v/python-openstackclient.svg
+    :target: https://pypi.org/project/python-openstackclient/
+    :alt: Latest Version
+
+OpenStackClient (OSC) is a command-line client for OpenStack that brings
+the command set for Compute, Identity, Image, Network, Object Store and Block
+Storage APIs together in a single shell with a uniform command structure.
+Support for additional service APIs is provided via plugins.
+
+The primary goal is to provide a unified shell command structure and a common
+language to describe operations in OpenStack.
+
+Getting Started
+===============
+
+OpenStack Client can be installed from PyPI using pip:
+
+.. code-block:: shell
+
+    python3 -m pip install python-openstackclient
+
+You can use ``--help`` or the ``help`` command to get a list of global options
+and supported commands:
+
+.. code-block:: shell
+
+    openstack --help
+    openstack help
+
+You can also get help for a specific command:
+
+.. code-block:: shell
+
+    openstack server create --help
+    openstack help server create
+
+You can add support for additional services by installing their clients. For
+example, to add support for the DNS service (designate):
+
+.. code-block:: shell
+
+    python3 -m pip install python3-designateclient
+
+A ``Dockerfile`` is provided for your convenience in the repository. You can
+use this to build your own container images:
+
+.. code-block:: shell
+
+    git clone https://opendev.org/openstack/python-openstackclient
+    cd python-openstackclient
+    podman build . -t example.com/myuser/openstackclient
+
+For more information the available options and commands, refer to the `Users
+Guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/cli/index.html
+
+Configuration
+=============
+
+OpenStack Client must be configured with authentication information in order to
+communicate with a given OpenStack cloud. This configuration can be achieved
+via a ``clouds.yaml`` file, a set of environment variables (often shared via an
+``openrc`` file), a set of command-line options, or a combination of all three.
+Your cloud provider or deployment tooling will typically provide either a
+``clouds.yaml`` file or ``openrc`` file for you. If using a ``clouds.yaml``
+file, OpenStack Client expects to find it in one of the following locations:
+
+* If set, the path indicated by the ``OS_CLIENT_CONFIG_FILE`` environment
+  variable
+* ``.`` (the current directory)
+* ``$HOME/.config/openstack``
+* ``/etc/openstack``
+
+The options you should set will depend on the configuration of your cloud and
+the authentication mechanism(s) supported. For example, consider a cloud that
+supports username/password authentication. Configuration for this cloud using a
+``clouds.yaml`` file would look like so:
+
+.. code-block:: yaml
+
+    clouds:
+      my-cloud:
+        auth:
+          auth_url: '<url-to-openstack-identity>'
+          project_name: '<project-name>'
+          project_domain_name: '<project-domain-name>'
+          username: '<username>'
+          user_domain_name: '<user-domain-name>'
+          password: '<password>'  # (optional)
+        region_name: '<region>'
+
+The corresponding environment variables would look very similar:
+
+.. code-block:: shell
+
+    export OS_AUTH_URL=<url-to-openstack-identity>
+    export OS_REGION_NAME=<region>
+    export OS_PROJECT_NAME=<project-name>
+    export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+    export OS_USERNAME=<username>
+    export OS_USER_DOMAIN_NAME=<user-domain-name>
+    export OS_PASSWORD=<password>  # (optional)
+
+Likewise, the corresponding command-line options would look very similar:
+
+::
+
+    openstack
+    --os-auth-url <url-to-openstack-identity>
+    --os-region <region>
+    --os-project-name <project-name>
+    --os-project-domain-name <project-domain-name>
+    --os-username <username>
+    --os-user-domain-name <user-domain-name>
+    [--os-password <password>]
+
+.. note::
+
+    If a password is not provided above (in plaintext), you will be
+    interactively prompted to provide one securely.
+
+Some clouds use federated authentication. If this is the case, your
+configuration will be slightly more involved. For example, to configure
+username/password authentication for a federated user using a ``clouds.yaml``
+file:
+
+.. code-block:: yaml
+
+    clouds:
+      my-cloud:
+        auth:
+          auth_url: '<url-to-openstack-identity>'
+          project_name: '<project-name>'
+          project_domain_name: '<project-domain-name>'
+          username: '<username-in-idp>'
+          user_domain_name: '<user-domain-name>'
+          password: '<password-in-idp>'
+          identity_provider: '<the-desired-idp-in-keystone>'
+          client_id: '<the-client-id-configured-in-the-idp>'
+          client_secret: '<the-client-secret-configured-in-the-idp>'
+          openid_scope: '<the-scopes-of-desired-attributes-to-claim-from-idp>'
+          protocol: '<the-protocol-used-in-the-apache2-oidc-proxy>'
+          access_token_type: '<the-access-token-type-used-by-your-idp>'
+          discovery_endpoint: '<the-well-known-endpoint-of-the-idp>'
+        auth_type: 'v3oidcpassword'
+        region_name: '<region>'
+
+The corresponding environment variables would look very similar:
+
+.. code-block:: shell
+
+    export OS_PROJECT_NAME=<project-name>
+    export OS_PROJECT_DOMAIN_NAME=<project-domain-name>
+    export OS_AUTH_URL=<url-to-openstack-identity>
+    export OS_IDENTITY_API_VERSION=3
+    export OS_AUTH_TYPE=v3oidcpassword
+    export OS_USERNAME=<username-in-idp>
+    export OS_PASSWORD=<password-in-idp>
+    export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone>
+    export OS_CLIENT_ID=<the-client-id-configured-in-the-idp>
+    export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp>
+    export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp>
+    export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy>
+    export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp>
+    export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp>
+
+Likewise, the corresponding command-line options would look very similar:
+
+.. code-block:: shell
+
+    --os-project-name <project-name>
+    --os-project-domain-name <project-domain-name>
+    --os-auth-url <url-to-openstack-identity>
+    --os-identity-api-version 3
+    --os-auth-plugin openid
+    --os-auth-type v3oidcpassword
+    --os-username <username-in-idp>
+    --os-password <password-in-idp>
+    --os-identity-provider <the-desired-idp-in-keystone>
+    --os-client-id <the-client-id-configured-in-the-idp>
+    --os-client-secret <the-client-secred-configured-in-the-idp>
+    --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp>
+    --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy>
+    --os-access-token-type <the-access-token-type-used-by-your-idp>
+    --os-discovery-endpoint <the-well-known-endpoint-of-the-idp>
+
+For more information on configuring authentication, including an overview of
+the many authentication mechanisms supported, refer to the `Authentication
+guide`__. For more information on configuration in general, refer to the
+`Configuration guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html.
+.. __: https://docs.openstack.org/python-openstackclient/latest/configuration/index.html
+
+Contributing
+============
+
+You can clone the repository from opendev.org::
+
+    git clone https://opendev.org/openstack/python-openstackclient
+    cd python-openstackclient
+
+OpenStack Client uses the same contributor process as other OpenStack projects.
+For information on this process, including help on setting up you Gerrit
+account and an overview of the CI process, refer to the `OpenStack Contributors
+Guide`__.
+
+For more information on contributing to OpenStack Client itself, including
+guidance on how to design new commands and how to report bugs, refer to the
+`Contributors Guide`__.
+
+.. __: https://docs.openstack.org/python-openstackclient/latest/contributor/index.html
+.. __: https://docs.opendev.org/opendev/infra-manual/latest/developers.html
+
+Links
+-----
+
+* `Issue Tracker <https://bugs.launchpad.net/python-openstackclient>`_
+* `Code Review <https://review.opendev.org/#/q/status:open+project:openstack/openstacksdk,n,z>`_
+* `Documentation <https://docs.openstack.org/python-openstackclient/latest/>`_
+* `PyPi <https://pypi.org/project/python-openstackclient>`_
+* `Mailing list <https://lists.openstack.org/mailman3/lists/openstack-discuss.lists.openstack.org/>`_
+* `Release Notes <https://docs.openstack.org/releasenotes/python-openstackclient>`_
+* `IRC (#openstack-sdks on OFTC (irc.oftc.net)) <irc://irc.oftc.net/openstack-sdks>`_
diff -pruN 7.4.0-3/python_openstackclient.egg-info/SOURCES.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/SOURCES.txt
--- 7.4.0-3/python_openstackclient.egg-info/SOURCES.txt	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/SOURCES.txt	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1,1403 @@
+.coveragerc
+.git-blame-ignore-revs
+.mailmap
+.pre-commit-config.yaml
+.stestr.conf
+.zuul.yaml
+AUTHORS
+CONTRIBUTING.rst
+ChangeLog
+Dockerfile
+HACKING.rst
+LICENSE
+README.rst
+bindep.txt
+pyproject.toml
+requirements.txt
+setup.cfg
+setup.py
+test-requirements.txt
+tox.ini
+doc/Makefile
+doc/requirements.txt
+doc/source/conf.py
+doc/source/index.rst
+doc/source/_extra/.htaccess
+doc/source/cli/authentication.rst
+doc/source/cli/backwards-incompatible.rst
+doc/source/cli/command-list.rst
+doc/source/cli/commands.rst
+doc/source/cli/decoder.rst
+doc/source/cli/index.rst
+doc/source/cli/interactive.rst
+doc/source/cli/_hidden/ec2-credentials.rst
+doc/source/cli/_hidden/endpoint.rst
+doc/source/cli/_hidden/image.rst
+doc/source/cli/_hidden/project.rst
+doc/source/cli/_hidden/role.rst
+doc/source/cli/_hidden/service.rst
+doc/source/cli/_hidden/token.rst
+doc/source/cli/_hidden/user.rst
+doc/source/cli/command-objects/access-rules.rst
+doc/source/cli/command-objects/access-token.rst
+doc/source/cli/command-objects/address-group.rst
+doc/source/cli/command-objects/address-scope.rst
+doc/source/cli/command-objects/aggregate.rst
+doc/source/cli/command-objects/application-credentials.rst
+doc/source/cli/command-objects/availability-zone.rst
+doc/source/cli/command-objects/block-storage-cleanup.rst
+doc/source/cli/command-objects/block-storage-cluster.rst
+doc/source/cli/command-objects/block-storage-log-level.rst
+doc/source/cli/command-objects/block-storage-manage.rst
+doc/source/cli/command-objects/block-storage-resource-filter.rst
+doc/source/cli/command-objects/catalog.rst
+doc/source/cli/command-objects/command.rst
+doc/source/cli/command-objects/complete.rst
+doc/source/cli/command-objects/compute-agent.rst
+doc/source/cli/command-objects/compute-service.rst
+doc/source/cli/command-objects/configuration.rst
+doc/source/cli/command-objects/consistency-group-snapshot.rst
+doc/source/cli/command-objects/consistency-group.rst
+doc/source/cli/command-objects/console-connection.rst
+doc/source/cli/command-objects/console-log.rst
+doc/source/cli/command-objects/console-url.rst
+doc/source/cli/command-objects/consumer.rst
+doc/source/cli/command-objects/container.rst
+doc/source/cli/command-objects/credential.rst
+doc/source/cli/command-objects/default-security-group-rule.rst
+doc/source/cli/command-objects/domain.rst
+doc/source/cli/command-objects/ec2-credentials-v2.rst
+doc/source/cli/command-objects/ec2-credentials-v3.rst
+doc/source/cli/command-objects/endpoint-v2.rst
+doc/source/cli/command-objects/endpoint-v3.rst
+doc/source/cli/command-objects/endpoint_group.rst
+doc/source/cli/command-objects/extension.rst
+doc/source/cli/command-objects/federation-domain-project.rst
+doc/source/cli/command-objects/federation-protocol.rst
+doc/source/cli/command-objects/flavor.rst
+doc/source/cli/command-objects/floating-ip-pool.rst
+doc/source/cli/command-objects/floating-ip-port-forwarding.rst
+doc/source/cli/command-objects/floating-ip.rst
+doc/source/cli/command-objects/group.rst
+doc/source/cli/command-objects/host.rst
+doc/source/cli/command-objects/hypervisor-stats.rst
+doc/source/cli/command-objects/hypervisor.rst
+doc/source/cli/command-objects/identity-provider.rst
+doc/source/cli/command-objects/image-member.rst
+doc/source/cli/command-objects/image-metadef.rst
+doc/source/cli/command-objects/image-task.rst
+doc/source/cli/command-objects/image-v1.rst
+doc/source/cli/command-objects/image-v2.rst
+doc/source/cli/command-objects/implied_role.rst
+doc/source/cli/command-objects/ip-availability.rst
+doc/source/cli/command-objects/keypair.rst
+doc/source/cli/command-objects/limit.rst
+doc/source/cli/command-objects/limits.rst
+doc/source/cli/command-objects/local-ip-association.rst
+doc/source/cli/command-objects/local-ip.rst
+doc/source/cli/command-objects/mapping.rst
+doc/source/cli/command-objects/module.rst
+doc/source/cli/command-objects/network-agent.rst
+doc/source/cli/command-objects/network-auto-allocated-topology.rst
+doc/source/cli/command-objects/network-flavor-profile.rst
+doc/source/cli/command-objects/network-flavor.rst
+doc/source/cli/command-objects/network-l3-conntrack-helper.rst
+doc/source/cli/command-objects/network-meter-rule.rst
+doc/source/cli/command-objects/network-meter.rst
+doc/source/cli/command-objects/network-qos-policy.rst
+doc/source/cli/command-objects/network-qos-rule-type.rst
+doc/source/cli/command-objects/network-qos-rule.rst
+doc/source/cli/command-objects/network-rbac.rst
+doc/source/cli/command-objects/network-segment.rst
+doc/source/cli/command-objects/network-service-provider.rst
+doc/source/cli/command-objects/network-trunk.rst
+doc/source/cli/command-objects/network.rst
+doc/source/cli/command-objects/network_segment_range.rst
+doc/source/cli/command-objects/object-store-account.rst
+doc/source/cli/command-objects/object.rst
+doc/source/cli/command-objects/policy.rst
+doc/source/cli/command-objects/port.rst
+doc/source/cli/command-objects/project-cleanup.rst
+doc/source/cli/command-objects/project-v2.rst
+doc/source/cli/command-objects/project-v3.rst
+doc/source/cli/command-objects/quota.rst
+doc/source/cli/command-objects/region.rst
+doc/source/cli/command-objects/registered-limit.rst
+doc/source/cli/command-objects/request-token.rst
+doc/source/cli/command-objects/role-assignment.rst
+doc/source/cli/command-objects/role-v2.rst
+doc/source/cli/command-objects/role-v3.rst
+doc/source/cli/command-objects/router-ndp-proxy.rst
+doc/source/cli/command-objects/router.rst
+doc/source/cli/command-objects/security-group-rule.rst
+doc/source/cli/command-objects/security-group.rst
+doc/source/cli/command-objects/server-backup.rst
+doc/source/cli/command-objects/server-event.rst
+doc/source/cli/command-objects/server-group.rst
+doc/source/cli/command-objects/server-image.rst
+doc/source/cli/command-objects/server-migration.rst
+doc/source/cli/command-objects/server.rst
+doc/source/cli/command-objects/service-provider.rst
+doc/source/cli/command-objects/service-v2.rst
+doc/source/cli/command-objects/service-v3.rst
+doc/source/cli/command-objects/subnet-pool.rst
+doc/source/cli/command-objects/subnet.rst
+doc/source/cli/command-objects/token-v2.rst
+doc/source/cli/command-objects/token-v3.rst
+doc/source/cli/command-objects/trust.rst
+doc/source/cli/command-objects/usage.rst
+doc/source/cli/command-objects/user-v2.rst
+doc/source/cli/command-objects/user-v3.rst
+doc/source/cli/command-objects/versions.rst
+doc/source/cli/command-objects/volume-attachment.rst
+doc/source/cli/command-objects/volume-backend.rst
+doc/source/cli/command-objects/volume-backup.rst
+doc/source/cli/command-objects/volume-group-snapshot.rst
+doc/source/cli/command-objects/volume-group-type.rst
+doc/source/cli/command-objects/volume-group.rst
+doc/source/cli/command-objects/volume-host.rst
+doc/source/cli/command-objects/volume-message.rst
+doc/source/cli/command-objects/volume-qos.rst
+doc/source/cli/command-objects/volume-service.rst
+doc/source/cli/command-objects/volume-snapshot.rst
+doc/source/cli/command-objects/volume-transfer-request.rst
+doc/source/cli/command-objects/volume-type.rst
+doc/source/cli/command-objects/volume.rst
+doc/source/cli/data/cinder.csv
+doc/source/cli/data/glance.csv
+doc/source/cli/data/keystone.csv
+doc/source/cli/data/neutron.csv
+doc/source/cli/data/nova.csv
+doc/source/cli/data/swift.csv
+doc/source/cli/man/openstack.rst
+doc/source/cli/plugin-commands/aodh.rst
+doc/source/cli/plugin-commands/barbican.rst
+doc/source/cli/plugin-commands/cyborg.rst
+doc/source/cli/plugin-commands/designate.rst
+doc/source/cli/plugin-commands/gnocchi.rst
+doc/source/cli/plugin-commands/heat.rst
+doc/source/cli/plugin-commands/index.rst
+doc/source/cli/plugin-commands/ironic-inspector.rst
+doc/source/cli/plugin-commands/ironic.rst
+doc/source/cli/plugin-commands/magnum.rst
+doc/source/cli/plugin-commands/manila.rst
+doc/source/cli/plugin-commands/mistral.rst
+doc/source/cli/plugin-commands/neutron.rst
+doc/source/cli/plugin-commands/octavia.rst
+doc/source/cli/plugin-commands/placement.rst
+doc/source/cli/plugin-commands/trove.rst
+doc/source/cli/plugin-commands/watcher.rst
+doc/source/cli/plugin-commands/zaqar.rst
+doc/source/cli/plugin-commands/zun.rst
+doc/source/configuration/index.rst
+doc/source/contributor/command-beta.rst
+doc/source/contributor/command-errors.rst
+doc/source/contributor/command-logs.rst
+doc/source/contributor/command-options.rst
+doc/source/contributor/command-wrappers.rst
+doc/source/contributor/developing.rst
+doc/source/contributor/humaninterfaceguide.rst
+doc/source/contributor/index.rst
+doc/source/contributor/plugins.rst
+doc/test/redirect-tests.txt
+examples/common.py
+examples/object_api.py
+examples/openstack.sh
+examples/osc-lib.py
+openstackclient/__init__.py
+openstackclient/i18n.py
+openstackclient/shell.py
+openstackclient/api/__init__.py
+openstackclient/api/api.py
+openstackclient/api/compute_v2.py
+openstackclient/api/image_v1.py
+openstackclient/api/image_v2.py
+openstackclient/api/object_store_v1.py
+openstackclient/common/__init__.py
+openstackclient/common/availability_zone.py
+openstackclient/common/clientmanager.py
+openstackclient/common/configuration.py
+openstackclient/common/envvars.py
+openstackclient/common/extension.py
+openstackclient/common/limits.py
+openstackclient/common/module.py
+openstackclient/common/pagination.py
+openstackclient/common/progressbar.py
+openstackclient/common/project_cleanup.py
+openstackclient/common/quota.py
+openstackclient/common/versions.py
+openstackclient/compute/__init__.py
+openstackclient/compute/client.py
+openstackclient/compute/v2/__init__.py
+openstackclient/compute/v2/agent.py
+openstackclient/compute/v2/aggregate.py
+openstackclient/compute/v2/console.py
+openstackclient/compute/v2/console_connection.py
+openstackclient/compute/v2/flavor.py
+openstackclient/compute/v2/host.py
+openstackclient/compute/v2/hypervisor.py
+openstackclient/compute/v2/hypervisor_stats.py
+openstackclient/compute/v2/keypair.py
+openstackclient/compute/v2/server.py
+openstackclient/compute/v2/server_backup.py
+openstackclient/compute/v2/server_event.py
+openstackclient/compute/v2/server_group.py
+openstackclient/compute/v2/server_image.py
+openstackclient/compute/v2/server_migration.py
+openstackclient/compute/v2/server_volume.py
+openstackclient/compute/v2/service.py
+openstackclient/compute/v2/usage.py
+openstackclient/identity/__init__.py
+openstackclient/identity/client.py
+openstackclient/identity/common.py
+openstackclient/identity/v2_0/__init__.py
+openstackclient/identity/v2_0/catalog.py
+openstackclient/identity/v2_0/ec2creds.py
+openstackclient/identity/v2_0/endpoint.py
+openstackclient/identity/v2_0/project.py
+openstackclient/identity/v2_0/role.py
+openstackclient/identity/v2_0/role_assignment.py
+openstackclient/identity/v2_0/service.py
+openstackclient/identity/v2_0/token.py
+openstackclient/identity/v2_0/user.py
+openstackclient/identity/v3/__init__.py
+openstackclient/identity/v3/access_rule.py
+openstackclient/identity/v3/application_credential.py
+openstackclient/identity/v3/catalog.py
+openstackclient/identity/v3/consumer.py
+openstackclient/identity/v3/credential.py
+openstackclient/identity/v3/domain.py
+openstackclient/identity/v3/ec2creds.py
+openstackclient/identity/v3/endpoint.py
+openstackclient/identity/v3/endpoint_group.py
+openstackclient/identity/v3/federation_protocol.py
+openstackclient/identity/v3/group.py
+openstackclient/identity/v3/identity_provider.py
+openstackclient/identity/v3/implied_role.py
+openstackclient/identity/v3/limit.py
+openstackclient/identity/v3/mapping.py
+openstackclient/identity/v3/policy.py
+openstackclient/identity/v3/project.py
+openstackclient/identity/v3/region.py
+openstackclient/identity/v3/registered_limit.py
+openstackclient/identity/v3/role.py
+openstackclient/identity/v3/role_assignment.py
+openstackclient/identity/v3/service.py
+openstackclient/identity/v3/service_provider.py
+openstackclient/identity/v3/tag.py
+openstackclient/identity/v3/token.py
+openstackclient/identity/v3/trust.py
+openstackclient/identity/v3/unscoped_saml.py
+openstackclient/identity/v3/user.py
+openstackclient/image/__init__.py
+openstackclient/image/client.py
+openstackclient/image/v1/__init__.py
+openstackclient/image/v1/image.py
+openstackclient/image/v2/__init__.py
+openstackclient/image/v2/cache.py
+openstackclient/image/v2/image.py
+openstackclient/image/v2/info.py
+openstackclient/image/v2/metadef_namespaces.py
+openstackclient/image/v2/metadef_objects.py
+openstackclient/image/v2/metadef_properties.py
+openstackclient/image/v2/metadef_resource_type_association.py
+openstackclient/image/v2/metadef_resource_types.py
+openstackclient/image/v2/task.py
+openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po
+openstackclient/network/__init__.py
+openstackclient/network/client.py
+openstackclient/network/common.py
+openstackclient/network/utils.py
+openstackclient/network/v2/__init__.py
+openstackclient/network/v2/address_group.py
+openstackclient/network/v2/address_scope.py
+openstackclient/network/v2/default_security_group_rule.py
+openstackclient/network/v2/floating_ip.py
+openstackclient/network/v2/floating_ip_pool.py
+openstackclient/network/v2/floating_ip_port_forwarding.py
+openstackclient/network/v2/ip_availability.py
+openstackclient/network/v2/l3_conntrack_helper.py
+openstackclient/network/v2/local_ip.py
+openstackclient/network/v2/local_ip_association.py
+openstackclient/network/v2/ndp_proxy.py
+openstackclient/network/v2/network.py
+openstackclient/network/v2/network_agent.py
+openstackclient/network/v2/network_auto_allocated_topology.py
+openstackclient/network/v2/network_flavor.py
+openstackclient/network/v2/network_flavor_profile.py
+openstackclient/network/v2/network_meter.py
+openstackclient/network/v2/network_meter_rule.py
+openstackclient/network/v2/network_qos_policy.py
+openstackclient/network/v2/network_qos_rule.py
+openstackclient/network/v2/network_qos_rule_type.py
+openstackclient/network/v2/network_rbac.py
+openstackclient/network/v2/network_segment.py
+openstackclient/network/v2/network_segment_range.py
+openstackclient/network/v2/network_service_provider.py
+openstackclient/network/v2/network_trunk.py
+openstackclient/network/v2/port.py
+openstackclient/network/v2/router.py
+openstackclient/network/v2/security_group.py
+openstackclient/network/v2/security_group_rule.py
+openstackclient/network/v2/subnet.py
+openstackclient/network/v2/subnet_pool.py
+openstackclient/object/__init__.py
+openstackclient/object/client.py
+openstackclient/object/v1/__init__.py
+openstackclient/object/v1/account.py
+openstackclient/object/v1/container.py
+openstackclient/object/v1/object.py
+openstackclient/releasenotes/notes/volume-backup-created-at-list-b49ec893ae1f6b0d.yaml
+openstackclient/tests/__init__.py
+openstackclient/tests/functional/__init__.py
+openstackclient/tests/functional/base.py
+openstackclient/tests/functional/common/__init__.py
+openstackclient/tests/functional/common/test_args.py
+openstackclient/tests/functional/common/test_availability_zone.py
+openstackclient/tests/functional/common/test_configuration.py
+openstackclient/tests/functional/common/test_extension.py
+openstackclient/tests/functional/common/test_help.py
+openstackclient/tests/functional/common/test_module.py
+openstackclient/tests/functional/common/test_quota.py
+openstackclient/tests/functional/common/test_versions.py
+openstackclient/tests/functional/compute/__init__.py
+openstackclient/tests/functional/compute/v2/__init__.py
+openstackclient/tests/functional/compute/v2/common.py
+openstackclient/tests/functional/compute/v2/test_aggregate.py
+openstackclient/tests/functional/compute/v2/test_flavor.py
+openstackclient/tests/functional/compute/v2/test_hypervisor.py
+openstackclient/tests/functional/compute/v2/test_keypair.py
+openstackclient/tests/functional/compute/v2/test_server.py
+openstackclient/tests/functional/compute/v2/test_server_event.py
+openstackclient/tests/functional/compute/v2/test_server_group.py
+openstackclient/tests/functional/identity/__init__.py
+openstackclient/tests/functional/identity/v2/__init__.py
+openstackclient/tests/functional/identity/v2/common.py
+openstackclient/tests/functional/identity/v2/test_catalog.py
+openstackclient/tests/functional/identity/v2/test_ec2_credentials.py
+openstackclient/tests/functional/identity/v2/test_endpoint.py
+openstackclient/tests/functional/identity/v2/test_project.py
+openstackclient/tests/functional/identity/v2/test_role.py
+openstackclient/tests/functional/identity/v2/test_service.py
+openstackclient/tests/functional/identity/v2/test_token.py
+openstackclient/tests/functional/identity/v2/test_user.py
+openstackclient/tests/functional/identity/v3/__init__.py
+openstackclient/tests/functional/identity/v3/common.py
+openstackclient/tests/functional/identity/v3/test_access_rule.py
+openstackclient/tests/functional/identity/v3/test_application_credential.py
+openstackclient/tests/functional/identity/v3/test_catalog.py
+openstackclient/tests/functional/identity/v3/test_domain.py
+openstackclient/tests/functional/identity/v3/test_endpoint.py
+openstackclient/tests/functional/identity/v3/test_group.py
+openstackclient/tests/functional/identity/v3/test_idp.py
+openstackclient/tests/functional/identity/v3/test_limit.py
+openstackclient/tests/functional/identity/v3/test_project.py
+openstackclient/tests/functional/identity/v3/test_region.py
+openstackclient/tests/functional/identity/v3/test_registered_limit.py
+openstackclient/tests/functional/identity/v3/test_role.py
+openstackclient/tests/functional/identity/v3/test_role_assignment.py
+openstackclient/tests/functional/identity/v3/test_service.py
+openstackclient/tests/functional/identity/v3/test_service_provider.py
+openstackclient/tests/functional/identity/v3/test_token.py
+openstackclient/tests/functional/identity/v3/test_user.py
+openstackclient/tests/functional/image/__init__.py
+openstackclient/tests/functional/image/base.py
+openstackclient/tests/functional/image/v1/__init__.py
+openstackclient/tests/functional/image/v1/test_image.py
+openstackclient/tests/functional/image/v2/__init__.py
+openstackclient/tests/functional/image/v2/test_image.py
+openstackclient/tests/functional/image/v2/test_info.py
+openstackclient/tests/functional/network/__init__.py
+openstackclient/tests/functional/network/v2/__init__.py
+openstackclient/tests/functional/network/v2/common.py
+openstackclient/tests/functional/network/v2/test_address_group.py
+openstackclient/tests/functional/network/v2/test_address_scope.py
+openstackclient/tests/functional/network/v2/test_default_security_group_rule.py
+openstackclient/tests/functional/network/v2/test_floating_ip.py
+openstackclient/tests/functional/network/v2/test_ip_availability.py
+openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py
+openstackclient/tests/functional/network/v2/test_local_ip.py
+openstackclient/tests/functional/network/v2/test_network.py
+openstackclient/tests/functional/network/v2/test_network_agent.py
+openstackclient/tests/functional/network/v2/test_network_flavor.py
+openstackclient/tests/functional/network/v2/test_network_flavor_profile.py
+openstackclient/tests/functional/network/v2/test_network_meter.py
+openstackclient/tests/functional/network/v2/test_network_meter_rule.py
+openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py
+openstackclient/tests/functional/network/v2/test_network_qos_policy.py
+openstackclient/tests/functional/network/v2/test_network_qos_rule.py
+openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py
+openstackclient/tests/functional/network/v2/test_network_rbac.py
+openstackclient/tests/functional/network/v2/test_network_segment.py
+openstackclient/tests/functional/network/v2/test_network_segment_range.py
+openstackclient/tests/functional/network/v2/test_network_service_provider.py
+openstackclient/tests/functional/network/v2/test_network_trunk.py
+openstackclient/tests/functional/network/v2/test_port.py
+openstackclient/tests/functional/network/v2/test_router.py
+openstackclient/tests/functional/network/v2/test_security_group.py
+openstackclient/tests/functional/network/v2/test_security_group_rule.py
+openstackclient/tests/functional/network/v2/test_subnet.py
+openstackclient/tests/functional/network/v2/test_subnet_pool.py
+openstackclient/tests/functional/object/__init__.py
+openstackclient/tests/functional/object/v1/__init__.py
+openstackclient/tests/functional/object/v1/common.py
+openstackclient/tests/functional/object/v1/test_container.py
+openstackclient/tests/functional/object/v1/test_object.py
+openstackclient/tests/functional/volume/__init__.py
+openstackclient/tests/functional/volume/base.py
+openstackclient/tests/functional/volume/v2/__init__.py
+openstackclient/tests/functional/volume/v2/common.py
+openstackclient/tests/functional/volume/v2/test_qos.py
+openstackclient/tests/functional/volume/v2/test_service.py
+openstackclient/tests/functional/volume/v2/test_transfer_request.py
+openstackclient/tests/functional/volume/v2/test_volume.py
+openstackclient/tests/functional/volume/v2/test_volume_backup.py
+openstackclient/tests/functional/volume/v2/test_volume_snapshot.py
+openstackclient/tests/functional/volume/v2/test_volume_type.py
+openstackclient/tests/functional/volume/v3/__init__.py
+openstackclient/tests/functional/volume/v3/common.py
+openstackclient/tests/functional/volume/v3/test_qos.py
+openstackclient/tests/functional/volume/v3/test_transfer_request.py
+openstackclient/tests/functional/volume/v3/test_volume.py
+openstackclient/tests/functional/volume/v3/test_volume_snapshot.py
+openstackclient/tests/functional/volume/v3/test_volume_type.py
+openstackclient/tests/unit/__init__.py
+openstackclient/tests/unit/fakes.py
+openstackclient/tests/unit/test_shell.py
+openstackclient/tests/unit/utils.py
+openstackclient/tests/unit/api/__init__.py
+openstackclient/tests/unit/api/fakes.py
+openstackclient/tests/unit/api/test_api.py
+openstackclient/tests/unit/api/test_compute_v2.py
+openstackclient/tests/unit/api/test_image_v1.py
+openstackclient/tests/unit/api/test_image_v2.py
+openstackclient/tests/unit/api/test_object_store_v1.py
+openstackclient/tests/unit/common/__init__.py
+openstackclient/tests/unit/common/test_availability_zone.py
+openstackclient/tests/unit/common/test_clientmanager.py
+openstackclient/tests/unit/common/test_command.py
+openstackclient/tests/unit/common/test_configuration.py
+openstackclient/tests/unit/common/test_extension.py
+openstackclient/tests/unit/common/test_limits.py
+openstackclient/tests/unit/common/test_logs.py
+openstackclient/tests/unit/common/test_module.py
+openstackclient/tests/unit/common/test_progressbar.py
+openstackclient/tests/unit/common/test_project_cleanup.py
+openstackclient/tests/unit/common/test_quota.py
+openstackclient/tests/unit/compute/__init__.py
+openstackclient/tests/unit/compute/v2/__init__.py
+openstackclient/tests/unit/compute/v2/fakes.py
+openstackclient/tests/unit/compute/v2/test_agent.py
+openstackclient/tests/unit/compute/v2/test_aggregate.py
+openstackclient/tests/unit/compute/v2/test_console.py
+openstackclient/tests/unit/compute/v2/test_console_connection.py
+openstackclient/tests/unit/compute/v2/test_flavor.py
+openstackclient/tests/unit/compute/v2/test_host.py
+openstackclient/tests/unit/compute/v2/test_hypervisor.py
+openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py
+openstackclient/tests/unit/compute/v2/test_keypair.py
+openstackclient/tests/unit/compute/v2/test_server.py
+openstackclient/tests/unit/compute/v2/test_server_backup.py
+openstackclient/tests/unit/compute/v2/test_server_event.py
+openstackclient/tests/unit/compute/v2/test_server_group.py
+openstackclient/tests/unit/compute/v2/test_server_image.py
+openstackclient/tests/unit/compute/v2/test_server_migration.py
+openstackclient/tests/unit/compute/v2/test_server_volume.py
+openstackclient/tests/unit/compute/v2/test_service.py
+openstackclient/tests/unit/compute/v2/test_usage.py
+openstackclient/tests/unit/identity/__init__.py
+openstackclient/tests/unit/identity/v2_0/__init__.py
+openstackclient/tests/unit/identity/v2_0/fakes.py
+openstackclient/tests/unit/identity/v2_0/test_catalog.py
+openstackclient/tests/unit/identity/v2_0/test_endpoint.py
+openstackclient/tests/unit/identity/v2_0/test_project.py
+openstackclient/tests/unit/identity/v2_0/test_role.py
+openstackclient/tests/unit/identity/v2_0/test_role_assignment.py
+openstackclient/tests/unit/identity/v2_0/test_service.py
+openstackclient/tests/unit/identity/v2_0/test_token.py
+openstackclient/tests/unit/identity/v2_0/test_user.py
+openstackclient/tests/unit/identity/v3/__init__.py
+openstackclient/tests/unit/identity/v3/fakes.py
+openstackclient/tests/unit/identity/v3/test_access_rule.py
+openstackclient/tests/unit/identity/v3/test_application_credential.py
+openstackclient/tests/unit/identity/v3/test_catalog.py
+openstackclient/tests/unit/identity/v3/test_consumer.py
+openstackclient/tests/unit/identity/v3/test_credential.py
+openstackclient/tests/unit/identity/v3/test_domain.py
+openstackclient/tests/unit/identity/v3/test_endpoint.py
+openstackclient/tests/unit/identity/v3/test_endpoint_group.py
+openstackclient/tests/unit/identity/v3/test_group.py
+openstackclient/tests/unit/identity/v3/test_identity_provider.py
+openstackclient/tests/unit/identity/v3/test_implied_role.py
+openstackclient/tests/unit/identity/v3/test_limit.py
+openstackclient/tests/unit/identity/v3/test_mappings.py
+openstackclient/tests/unit/identity/v3/test_oauth.py
+openstackclient/tests/unit/identity/v3/test_project.py
+openstackclient/tests/unit/identity/v3/test_protocol.py
+openstackclient/tests/unit/identity/v3/test_region.py
+openstackclient/tests/unit/identity/v3/test_registered_limit.py
+openstackclient/tests/unit/identity/v3/test_role.py
+openstackclient/tests/unit/identity/v3/test_role_assignment.py
+openstackclient/tests/unit/identity/v3/test_service.py
+openstackclient/tests/unit/identity/v3/test_service_provider.py
+openstackclient/tests/unit/identity/v3/test_token.py
+openstackclient/tests/unit/identity/v3/test_trust.py
+openstackclient/tests/unit/identity/v3/test_unscoped_saml.py
+openstackclient/tests/unit/identity/v3/test_user.py
+openstackclient/tests/unit/image/__init__.py
+openstackclient/tests/unit/image/v1/__init__.py
+openstackclient/tests/unit/image/v1/fakes.py
+openstackclient/tests/unit/image/v1/test_image.py
+openstackclient/tests/unit/image/v2/__init__.py
+openstackclient/tests/unit/image/v2/fakes.py
+openstackclient/tests/unit/image/v2/test_cache.py
+openstackclient/tests/unit/image/v2/test_image.py
+openstackclient/tests/unit/image/v2/test_info.py
+openstackclient/tests/unit/image/v2/test_metadef_namespaces.py
+openstackclient/tests/unit/image/v2/test_metadef_objects.py
+openstackclient/tests/unit/image/v2/test_metadef_properties.py
+openstackclient/tests/unit/image/v2/test_metadef_resource_type_association.py
+openstackclient/tests/unit/image/v2/test_metadef_resource_types.py
+openstackclient/tests/unit/image/v2/test_task.py
+openstackclient/tests/unit/integ/__init__.py
+openstackclient/tests/unit/integ/base.py
+openstackclient/tests/unit/integ/cli/__init__.py
+openstackclient/tests/unit/integ/cli/test_project.py
+openstackclient/tests/unit/integ/cli/test_shell.py
+openstackclient/tests/unit/network/__init__.py
+openstackclient/tests/unit/network/test_common.py
+openstackclient/tests/unit/network/test_utils.py
+openstackclient/tests/unit/network/v2/__init__.py
+openstackclient/tests/unit/network/v2/fakes.py
+openstackclient/tests/unit/network/v2/test_address_group.py
+openstackclient/tests/unit/network/v2/test_address_scope.py
+openstackclient/tests/unit/network/v2/test_default_security_group_rule.py
+openstackclient/tests/unit/network/v2/test_floating_ip_compute.py
+openstackclient/tests/unit/network/v2/test_floating_ip_network.py
+openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py
+openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py
+openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py
+openstackclient/tests/unit/network/v2/test_ip_availability.py
+openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py
+openstackclient/tests/unit/network/v2/test_local_ip.py
+openstackclient/tests/unit/network/v2/test_local_ip_association.py
+openstackclient/tests/unit/network/v2/test_ndp_proxy.py
+openstackclient/tests/unit/network/v2/test_network.py
+openstackclient/tests/unit/network/v2/test_network_agent.py
+openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py
+openstackclient/tests/unit/network/v2/test_network_compute.py
+openstackclient/tests/unit/network/v2/test_network_flavor.py
+openstackclient/tests/unit/network/v2/test_network_flavor_profile.py
+openstackclient/tests/unit/network/v2/test_network_meter.py
+openstackclient/tests/unit/network/v2/test_network_meter_rule.py
+openstackclient/tests/unit/network/v2/test_network_qos_policy.py
+openstackclient/tests/unit/network/v2/test_network_qos_rule.py
+openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py
+openstackclient/tests/unit/network/v2/test_network_rbac.py
+openstackclient/tests/unit/network/v2/test_network_segment.py
+openstackclient/tests/unit/network/v2/test_network_segment_range.py
+openstackclient/tests/unit/network/v2/test_network_service_provider.py
+openstackclient/tests/unit/network/v2/test_network_trunk.py
+openstackclient/tests/unit/network/v2/test_port.py
+openstackclient/tests/unit/network/v2/test_router.py
+openstackclient/tests/unit/network/v2/test_security_group_compute.py
+openstackclient/tests/unit/network/v2/test_security_group_network.py
+openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py
+openstackclient/tests/unit/network/v2/test_security_group_rule_network.py
+openstackclient/tests/unit/network/v2/test_subnet.py
+openstackclient/tests/unit/network/v2/test_subnet_pool.py
+openstackclient/tests/unit/object/__init__.py
+openstackclient/tests/unit/object/v1/__init__.py
+openstackclient/tests/unit/object/v1/fakes.py
+openstackclient/tests/unit/object/v1/test_container.py
+openstackclient/tests/unit/object/v1/test_container_all.py
+openstackclient/tests/unit/object/v1/test_object.py
+openstackclient/tests/unit/object/v1/test_object_all.py
+openstackclient/tests/unit/volume/__init__.py
+openstackclient/tests/unit/volume/test_find_resource.py
+openstackclient/tests/unit/volume/v2/__init__.py
+openstackclient/tests/unit/volume/v2/fakes.py
+openstackclient/tests/unit/volume/v2/test_backup_record.py
+openstackclient/tests/unit/volume/v2/test_consistency_group.py
+openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py
+openstackclient/tests/unit/volume/v2/test_qos_specs.py
+openstackclient/tests/unit/volume/v2/test_service.py
+openstackclient/tests/unit/volume/v2/test_volume.py
+openstackclient/tests/unit/volume/v2/test_volume_backend.py
+openstackclient/tests/unit/volume/v2/test_volume_backup.py
+openstackclient/tests/unit/volume/v2/test_volume_host.py
+openstackclient/tests/unit/volume/v2/test_volume_snapshot.py
+openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py
+openstackclient/tests/unit/volume/v2/test_volume_type.py
+openstackclient/tests/unit/volume/v3/__init__.py
+openstackclient/tests/unit/volume/v3/fakes.py
+openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py
+openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py
+openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py
+openstackclient/tests/unit/volume/v3/test_block_storage_manage.py
+openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py
+openstackclient/tests/unit/volume/v3/test_service.py
+openstackclient/tests/unit/volume/v3/test_volume.py
+openstackclient/tests/unit/volume/v3/test_volume_attachment.py
+openstackclient/tests/unit/volume/v3/test_volume_backup.py
+openstackclient/tests/unit/volume/v3/test_volume_group.py
+openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py
+openstackclient/tests/unit/volume/v3/test_volume_group_type.py
+openstackclient/tests/unit/volume/v3/test_volume_message.py
+openstackclient/tests/unit/volume/v3/test_volume_snapshot.py
+openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py
+openstackclient/tests/unit/volume/v3/test_volume_type.py
+openstackclient/volume/__init__.py
+openstackclient/volume/client.py
+openstackclient/volume/v2/__init__.py
+openstackclient/volume/v2/backup_record.py
+openstackclient/volume/v2/consistency_group.py
+openstackclient/volume/v2/consistency_group_snapshot.py
+openstackclient/volume/v2/qos_specs.py
+openstackclient/volume/v2/service.py
+openstackclient/volume/v2/volume.py
+openstackclient/volume/v2/volume_backend.py
+openstackclient/volume/v2/volume_backup.py
+openstackclient/volume/v2/volume_host.py
+openstackclient/volume/v2/volume_snapshot.py
+openstackclient/volume/v2/volume_transfer_request.py
+openstackclient/volume/v2/volume_type.py
+openstackclient/volume/v3/__init__.py
+openstackclient/volume/v3/block_storage_cleanup.py
+openstackclient/volume/v3/block_storage_cluster.py
+openstackclient/volume/v3/block_storage_log_level.py
+openstackclient/volume/v3/block_storage_manage.py
+openstackclient/volume/v3/block_storage_resource_filter.py
+openstackclient/volume/v3/service.py
+openstackclient/volume/v3/volume.py
+openstackclient/volume/v3/volume_attachment.py
+openstackclient/volume/v3/volume_backup.py
+openstackclient/volume/v3/volume_group.py
+openstackclient/volume/v3/volume_group_snapshot.py
+openstackclient/volume/v3/volume_group_type.py
+openstackclient/volume/v3/volume_message.py
+openstackclient/volume/v3/volume_snapshot.py
+openstackclient/volume/v3/volume_transfer_request.py
+openstackclient/volume/v3/volume_type.py
+python_openstackclient.egg-info/PKG-INFO
+python_openstackclient.egg-info/SOURCES.txt
+python_openstackclient.egg-info/dependency_links.txt
+python_openstackclient.egg-info/entry_points.txt
+python_openstackclient.egg-info/not-zip-safe
+python_openstackclient.egg-info/pbr.json
+python_openstackclient.egg-info/requires.txt
+python_openstackclient.egg-info/top_level.txt
+releasenotes/notes/.placeholder
+releasenotes/notes/Add-default-security-group-rule-CRUD-2916568f829ea38c.yaml
+releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml
+releasenotes/notes/L3-conntrack-helper-bd0d9da041747e84.yaml
+releasenotes/notes/Router-flavor-accepts-name-or-id-e9cecafcddf81cb2.yaml
+releasenotes/notes/add-auto-and-none-as-nic-parameter-ed23a6e7f99f250d.yaml
+releasenotes/notes/add-auto-approve-cleanup-a2d225faa42dfdcb.yaml
+releasenotes/notes/add-backup-option-to-create-vol-fc36c2c745ebcff5.yaml
+releasenotes/notes/add-baremetal-agent-type-7c46365e8d457ac8.yaml
+releasenotes/notes/add-block-storage-cluster-commands-fae8f686582bbbcf.yaml
+releasenotes/notes/add-block-storage-manage-commands-6ebf029bd7a67bb3.yaml
+releasenotes/notes/add-cache-commands-a6f046348a3a0b1f.yaml
+releasenotes/notes/add-cluster-to-service-list-5eab3e828de7547e.yaml
+releasenotes/notes/add-community-option-to-image-list-ac0651eb2e5d632f.yaml
+releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml
+releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml
+releasenotes/notes/add-description-to-role-afe7b6ff668df261.yaml
+releasenotes/notes/add-device_id-to-port-list-0c658db51ce43c9e.yaml
+releasenotes/notes/add-disable-reason-6e0f28459a09a60d.yaml
+releasenotes/notes/add-dns-nameserver-overwrite-option-b866baeae12f9460.yaml
+releasenotes/notes/add-fip-portforwarding-commands-6e4d8ace698ee308.yaml
+releasenotes/notes/add-flavor-id-to-router-create-76e916e129b5b80c.yaml
+releasenotes/notes/add-ha-to-router-update-6a38a73cc112b2fc.yaml
+releasenotes/notes/add-host-and-hypervisor-hostname-flag-to-create-server-cb8b39a9f9311d42.yaml
+releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml
+releasenotes/notes/add-image-member-get-25e913ef2b861bf3.yaml
+releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml
+releasenotes/notes/add-image-metadef-namespace-support-4ba37ec3a1a72185.yaml
+releasenotes/notes/add-image-metadef-object-property-show-4ab2c957451ea230.yaml
+releasenotes/notes/add-image-metadef-object-update-f4880e423bf4faba.yaml
+releasenotes/notes/add-image-metadef-resource-type-association-commands-4d373d7d8eca5d55.yaml
+releasenotes/notes/add-image-metadef-resource-type-list-command-020adcaa2ad14e07.yaml
+releasenotes/notes/add-image-progress-option-to-create-1ed1881d58ebad4b.yaml
+releasenotes/notes/add-image-project-filter-support-ed6204391e503adf.yaml
+releasenotes/notes/add-image-tag-filter-support-5cb039416b07caab.yaml
+releasenotes/notes/add-image-task-commands-50c3643ebfd0421f.yaml
+releasenotes/notes/add-implied-role-0cdafb131fbd7453.yaml
+releasenotes/notes/add-import-info-stores-delete-c50b5222c21e1077.yaml
+releasenotes/notes/add-is-default-to-network-qos-policy-89b11d4df032a789.yaml
+releasenotes/notes/add-keypairs-project-filter-99cb6938f247927f.yaml
+releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml
+releasenotes/notes/add-ksa-7f0795157d93a898.yaml
+releasenotes/notes/add-member-status-filter-2e118b2c93151223.yaml
+releasenotes/notes/add-metadef-object-create-3939ee1453585484.yaml
+releasenotes/notes/add-metadef-object-list-c8831e73c696b9d9.yaml
+releasenotes/notes/add-metadef-object-show-1b05dd33ecf42210.yaml
+releasenotes/notes/add-metadef-property-create-c9a4ec2bced892af.yaml
+releasenotes/notes/add-metadef-property-delete-ebb999d92a588ad4.yaml
+releasenotes/notes/add-metadef-property-list-fe89ae8ff9780002.yaml
+releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml
+releasenotes/notes/add-metadef-property-show-8bf2ec421f74cb2d.yaml
+releasenotes/notes/add-missing-hypervisor-list-opts-71da2cc36eac4edd.yaml
+releasenotes/notes/add-missing-keypair-list-opts-243a33d8276f91b8.yaml
+releasenotes/notes/add-missing-server-create-opts-d5e32bd743e9e132.yaml
+releasenotes/notes/add-missing-server-delete-opts-071c3e054e3ce674.yaml
+releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml
+releasenotes/notes/add-missing-server-group-list-opts-ebcf84bfcea07a4b.yaml
+releasenotes/notes/add-missing-server-image-create-opts-3c19a7492dc50fd7.yaml
+releasenotes/notes/add-missing-server-list-opts-c41e97e86ff1e1ca.yaml
+releasenotes/notes/add-missing-server-rebuild-opts-5c75e838d8f0487d.yaml
+releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml
+releasenotes/notes/add-missing-trust-list-opts-500fd1e4c14e1504.yaml
+releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml
+releasenotes/notes/add-more-server-list-columns-4e3b87929dd330f7.yaml
+releasenotes/notes/add-network-auto-allocated-topology-481580f48840bfc4.yaml
+releasenotes/notes/add-network-flavor-profile-e7cc5b353c3ed9d9.yaml
+releasenotes/notes/add-network-list-option-to-ports-9d101344ddeb3e64.yaml
+releasenotes/notes/add-network-local-ip-df3a9ce7610d8b90.yaml
+releasenotes/notes/add-network-qos-policy-b8ad1e408d73c279.yaml
+releasenotes/notes/add-network-qos-rule-22cc1ddd509941db.yaml
+releasenotes/notes/add-network-qos-rule-type-show-57a714a1d428726e.yaml
+releasenotes/notes/add-network-qos-rule-types-337e464c6e81f29c.yaml
+releasenotes/notes/add-network-rbac-list-tenant-project-filter-1228f2287284e33c.yaml
+releasenotes/notes/add-network-service-provider-c161a4a328a8a408.yaml
+releasenotes/notes/add-no-property-f97e4b2f390cec06.yaml
+releasenotes/notes/add-option-to-unset-port-host-c76de9b1d2addf9a.yaml
+releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml
+releasenotes/notes/add-overwrite-option-to-router-7c50c8031dab6bae.yaml
+releasenotes/notes/add-parent-list-option-to-projects-10382a7176993366.yaml
+releasenotes/notes/add-port-commands-a3580662721a6312.yaml
+releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml
+releasenotes/notes/add-port-hardware-offload-type-011c98ab748357d7.yaml
+releasenotes/notes/add-port-hints-attribute-be1779e640a47d0d.yaml
+releasenotes/notes/add-port-list-status-option-f51da0aed0528a5d.yaml
+releasenotes/notes/add-port-numa-affinity-policy-4706b0f9485a5d4d.yaml
+releasenotes/notes/add-port-numa-affinity-policy-socket-5a986b14033e0f6e.yaml
+releasenotes/notes/add-port-ranges-in-port-forwarding-command-8c6ee05cf625578a.yaml
+releasenotes/notes/add-port-security-enabled-to-port-set-82b801d21d45e715.yaml
+releasenotes/notes/add-port-show-command-de0a599017189a21.yaml
+releasenotes/notes/add-port-unset-command-8bdaf1fa9c593374.yaml
+releasenotes/notes/add-project-cleanup-beb08c9df3c95b24.yaml
+releasenotes/notes/add-qos-policy-list-options-9ba1ae731a88e7ac.yaml
+releasenotes/notes/add-quota-list-command-0d865fac61db2430.yaml
+releasenotes/notes/add-quota-set-for-network-11fcd7b9e08624b5.yaml
+releasenotes/notes/add-reimage-param-to-rebuild-606dd331677b5954.yaml
+releasenotes/notes/add-remote-managed-vnic-type-4fc540b47427c37f.yaml
+releasenotes/notes/add-remove-multiple-security-groups-2c0b2d599124c9c9.yaml
+releasenotes/notes/add-restore-server-d8c73e0e83df17dd.yaml
+releasenotes/notes/add-server-add-network-98ede8ff6079eb23.yaml
+releasenotes/notes/add-server-backup-e63feaebb6140f83.yaml
+releasenotes/notes/add-server-create-image-property-ef76af26233b472b.yaml
+releasenotes/notes/add-server-evacuate-8359246692cb642f.yaml
+releasenotes/notes/add-server-group-quotas-b67fcba98619f0c9.yaml
+releasenotes/notes/add-server-hostname-opts-3cb4fd90b5bf47ca.yaml
+releasenotes/notes/add-server-migrate-confirm-revert-commands-9d8079c9fddea36d.yaml
+releasenotes/notes/add-server-migrate-with-host-4884a71903c5c8a9.yaml
+releasenotes/notes/add-server-migration-show-command-2e3a25e383dc5d70.yaml
+releasenotes/notes/add-server-nic-tagging-support-f77b4247e87771d5.yaml
+releasenotes/notes/add-server-remove-network-fb09c53d5b0c0068.yaml
+releasenotes/notes/add-server-resize-confirm-revert-commands-98854ca98965432a.yaml
+releasenotes/notes/add-server-volume-update-89740dca61596dd1.yaml
+releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml
+releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml
+releasenotes/notes/add-stores-info-9f1488dd29013767.yaml
+releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml
+releasenotes/notes/add-tag-support-server-add-fixed-ip-8de2db58f2a80e85.yaml
+releasenotes/notes/add-tag-support-server-add-network-a8590cab5d7babf0.yaml
+releasenotes/notes/add-tag-support-server-add-port-7e30aa38202d0839.yaml
+releasenotes/notes/add-tag-support-server-add-volume-278e79a22dd482f4.yaml
+releasenotes/notes/add-trusted-certs-option-server-create-a660488407300f22.yaml
+releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml
+releasenotes/notes/add-virtio-forwarder-vnic-type-bad939c6a868b9e9.yaml
+releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml
+releasenotes/notes/add-vol-service-get-set-log-commands-f9420e5061d994b5.yaml
+releasenotes/notes/add-volume-attachment-commands-db2974c6460fa3bc.yaml
+releasenotes/notes/add-volume-group-commands-b121d6ec7da9779a.yaml
+releasenotes/notes/add-volume-group-snapshot-commands-27fa8920d55f6bdb.yaml
+releasenotes/notes/add-volume-group-type-commands-13eabc7664a5c2bc.yaml
+releasenotes/notes/add-volume-host-failover-8fc77b24533b7fed.yaml
+releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml
+releasenotes/notes/add-volume-manage-command-088890446d0e81c7.yaml
+releasenotes/notes/add-volume-message-commands-89a590a1549c333e.yaml
+releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml
+releasenotes/notes/add-volume-revert-command-1c8f695420acbe7e.yaml
+releasenotes/notes/add-volume-summary-command-b2175b48af3ccab1.yaml
+releasenotes/notes/add-volume-transfer-request-create-snapshots-opts-1361416d37021e89.yaml
+releasenotes/notes/add-volume-type-set-public-private-opts-891fc7ab5de9bb6a.yaml
+releasenotes/notes/add-volume-unmanage-support-9b7139e5e948de77.yaml
+releasenotes/notes/add-workers-cleanup-command-720573c0f642efe9.yaml
+releasenotes/notes/add_attachment_id_to_volume_attachment-cea605585db29e14.yaml
+releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml
+releasenotes/notes/add_name_and_enabled_to_list_domain-6d23f02994b51c67.yaml
+releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml
+releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml
+releasenotes/notes/add_volume_backend_commands_to_volumeV3-145b114e40ab8615.yaml
+releasenotes/notes/address-scope-delete-multi-31c3af73feb31265.yaml
+releasenotes/notes/aggregate-list-uuid-column-808a0d051006a5ef.yaml
+releasenotes/notes/allow-custom-logging-12d55f8ed859ff8e.yaml
+releasenotes/notes/allow-port-create-with-extra-dhcp-options-c2c40e4002b52e2a.yaml
+releasenotes/notes/allow-port-list-with-ip-address-substr-14c5805b241e402f.yaml
+releasenotes/notes/allow-to-add-remove-vm-ports-273593d7cc1982de.yaml
+releasenotes/notes/allow-to-create-legacy-router-cb4dcb44dde74684.yaml
+releasenotes/notes/allow-to-specify-vm-ip-to-publish-85f7207740c0cc8d.yaml
+releasenotes/notes/allow-to-vm-ip-to-add-7721ba64b863fa77.yaml
+releasenotes/notes/always-show-direction-for-sg-rule-130efc39bf67d79a.yaml
+releasenotes/notes/auto-configure-block-live-migration-437d461c914f8f2f.yaml
+releasenotes/notes/auto-no-network-options-f4ddb2bb7544d2f5.yaml
+releasenotes/notes/backup_list_all-projects_option-4bb23e0b9b075cac.yaml
+releasenotes/notes/better-ipv6-address-suppport-security-group-rules-95272847349982e5.yaml
+releasenotes/notes/block-storage-x-manageable-list-long-option-a16a4641acfcf781.yaml
+releasenotes/notes/bp-add-locked-reason-425efd2def1144f1.yaml
+releasenotes/notes/bp-add-user-id-field-to-the-migrations-table-299b99ccb1f12a1f.yaml
+releasenotes/notes/bp-address-groups-in-sg-rules-b3b7742e4e6f5745.yaml
+releasenotes/notes/bp-address-groups-in-sg-rules-e0dc7e889e107799.yaml
+releasenotes/notes/bp-allow-overwrite-set-options-190a9c6904d53dab.yaml
+releasenotes/notes/bp-application-credential-a7031a043efc4a25.yaml
+releasenotes/notes/bp-backup-snapshot-renamed-for-volume-resource-2d2d13ea8489a61f.yaml
+releasenotes/notes/bp-cinder-command-support-3db775ba331e113d.yaml
+releasenotes/notes/bp-cinder-command-support-413b6d80232f8ece.yaml
+releasenotes/notes/bp-cinder-command-support-7e3ae1fb4cd90407.yaml
+releasenotes/notes/bp-cinder-command-support-82dbadef47454c18.yaml
+releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml
+releasenotes/notes/bp-cinder-command-support-ff7acc531baae8c3.yaml
+releasenotes/notes/bp-extension-show-6f7e31a27dad0dc9.yaml
+releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml
+releasenotes/notes/bp-implement-network-agents-5eba48796318f094.yaml
+releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml
+releasenotes/notes/bp-multi-argument-network-e43e192ac95db94d.yaml
+releasenotes/notes/bp-network-command-options-2-e7b13a6a09f5d21e.yaml
+releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml
+releasenotes/notes/bp-network-l3-adv-commands-cc1df715a184f1b2.yaml
+releasenotes/notes/bp-network-segment-range-management-0abf03fe03eea149.yaml
+releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml
+releasenotes/notes/bp-neutron-client-descriptions-a80902b4295843cf.yaml
+releasenotes/notes/bp-neutron-client-descriptions-b65dd776f78b5a73.yaml
+releasenotes/notes/bp-neutron-client-metering-1ee703a48343ece1.yaml
+releasenotes/notes/bp-neutron-client-metering-6f8f9527c2a797fd.yaml
+releasenotes/notes/bp-neutron-client-rbac-bbd7b545b50d2bdf.yaml
+releasenotes/notes/bp-neutron-client-tag-ff24d13e5c70e052.yaml
+releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml
+releasenotes/notes/bp-project-tags-b544aef9672d415b.yaml
+releasenotes/notes/bp-routed-networks-3b502faa5cd96807.yaml
+releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml
+releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml
+releasenotes/notes/bp-support-multi-add-remove-9516f72cfacea11a.yaml
+releasenotes/notes/bp-support-no-property-in-aggregate-b74a42e00a65d14a.yaml
+releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-16e864223d51b50a.yaml
+releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-9179045f04815bbb.yaml
+releasenotes/notes/bp-unified-limits-58f166401534a4ff.yaml
+releasenotes/notes/bp-unified-limits-6c5fdb1c26805d86.yaml
+releasenotes/notes/bp-unshelve-to-host-9ce4b7abf81aeedf.yaml
+releasenotes/notes/bp-whitelist-extension-for-app-creds-9afd5009b374190b.yaml
+releasenotes/notes/bug-1204956-af47c7f34ecc19c3.yaml
+releasenotes/notes/bug-1411190-live-migration-host-655ae6befa6a3de2.yaml
+releasenotes/notes/bug-1475831-3caafd724d4ed644.yaml
+releasenotes/notes/bug-1486597-857e20262c038514.yaml
+releasenotes/notes/bug-1499657-eeb260849febacf3.yaml
+releasenotes/notes/bug-1513894-6d2f05db6e1df744.yaml
+releasenotes/notes/bug-1516661-757ef629f899cca3.yaml
+releasenotes/notes/bug-1517134-9efecb257910989c.yaml
+releasenotes/notes/bug-1517386-1c0aad8e3203b02b.yaml
+releasenotes/notes/bug-1518059-e2dbe6e4b2473f10.yaml
+releasenotes/notes/bug-1519181-932c1ff07ef16666.yaml
+releasenotes/notes/bug-1519502-d534db6c18adef20.yaml
+releasenotes/notes/bug-1519502-f72236598d14d350.yaml
+releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml
+releasenotes/notes/bug-1519510-3cde4643b33ebb7a.yaml
+releasenotes/notes/bug-1519511-65b8901ae6ea2e63.yaml
+releasenotes/notes/bug-1519511-65d8d21dde31e5e2.yaml
+releasenotes/notes/bug-1519511-74bab0e0d32db043.yaml
+releasenotes/notes/bug-1519512-4231ac6014109142.yaml
+releasenotes/notes/bug-1519512-48624c5a32432a47.yaml
+releasenotes/notes/bug-1519512-48d98f09e44220a3.yaml
+releasenotes/notes/bug-1519512-65df002102b7fb99.yaml
+releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml
+releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml
+releasenotes/notes/bug-1520003-505af921c8afffc9.yaml
+releasenotes/notes/bug-1520115-0367e1c8917dc912.yaml
+releasenotes/notes/bug-1520541-44d45e4693089c03.yaml
+releasenotes/notes/bug-1521492-89b972c6362940a5.yaml
+releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml
+releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml
+releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml
+releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml
+releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml
+releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml
+releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml
+releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml
+releasenotes/notes/bug-1535213-c91133586e07d71c.yaml
+releasenotes/notes/bug-1535239-767e6cf1990eda01.yaml
+releasenotes/notes/bug-1535704-d6f013bfa22ab668.yaml
+releasenotes/notes/bug-1536479-d1f03ed2177d06ed.yaml
+releasenotes/notes/bug-1538372-ef3a30298357f972.yaml
+releasenotes/notes/bug-1540656-f7b7b7e3feef2440.yaml
+releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml
+releasenotes/notes/bug-1542171-fde165df53216726.yaml
+releasenotes/notes/bug-1542359-181d28db21a2358a.yaml
+releasenotes/notes/bug-1542362-ddad607f6d3025f0.yaml
+releasenotes/notes/bug-1542364-5d1e93cfd24f0b65.yaml
+releasenotes/notes/bug-1543214-959aee7830db2b0d.yaml
+releasenotes/notes/bug-1543222-6f8579344ff5c958.yaml
+releasenotes/notes/bug-1543226-7d885ecaa3715415.yaml
+releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml
+releasenotes/notes/bug-1544586-0e6ca9a09dac0726.yaml
+releasenotes/notes/bug-1544586-0fe19a567d3e31fc.yaml
+releasenotes/notes/bug-1544587-ec3ca453c1340b4e.yaml
+releasenotes/notes/bug-1544589-b9f669ef71aa5e57.yaml
+releasenotes/notes/bug-1544590-8cf42954e28c2f42.yaml
+releasenotes/notes/bug-1545537-12bbf01d2280dd2f.yaml
+releasenotes/notes/bug-1545537-4fa72fbfbbe3f31e.yaml
+releasenotes/notes/bug-1545537-7a66219d263bb1e5.yaml
+releasenotes/notes/bug-1545609-bdc1efc17214463b.yaml
+releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml
+releasenotes/notes/bug-1549410-8df3a4b12fe13ffa.yaml
+releasenotes/notes/bug-1550999-5e352a71dfbc828d.yaml
+releasenotes/notes/bug-1554877-7f8479791eab45b7.yaml
+releasenotes/notes/bug-1554886-8e5249a655e7e7b6.yaml
+releasenotes/notes/bug-1554889-32ba8d4bfb0f5f3d.yaml
+releasenotes/notes/bug-1556719-d2dcf61acf87e856.yaml
+releasenotes/notes/bug-1556929-edd78cded88ecdc9.yaml
+releasenotes/notes/bug-1559866-733988f5dd5b07bb.yaml
+releasenotes/notes/bug-1560157-bce572f58b43efa1.yaml
+releasenotes/notes/bug-1561599-d5f541f08ae6274a.yaml
+releasenotes/notes/bug-1561838-3a006a8263d7536d.yaml
+releasenotes/notes/bug-1564460-ab7ad35c02392cb4.yaml
+releasenotes/notes/bug-1565034-dd404bfb42d7778d.yaml
+releasenotes/notes/bug-1565112-e0cea9bfbcab954f.yaml
+releasenotes/notes/bug-1566090_64726dc7df5b1572.yaml
+releasenotes/notes/bug-1566269-2572bca9157ca107.yaml
+releasenotes/notes/bug-1569480-c52e330548bfbd78.yaml
+releasenotes/notes/bug-1571812-49cdce4df5f3d481.yaml
+releasenotes/notes/bug-1572228-03638a7adec5da8b.yaml
+releasenotes/notes/bug-1572733-874b37a7fa8292d0.yaml
+releasenotes/notes/bug-1575461-3fed33e53795684a.yaml
+releasenotes/notes/bug-1575461-4d7d90e792132064.yaml
+releasenotes/notes/bug-1575478-5a0a923c3a32f96a.yaml
+releasenotes/notes/bug-1575624-87957ff60ad661a6.yaml
+releasenotes/notes/bug-1578819-d1efccfefb18356d.yaml
+releasenotes/notes/bug-1581179-4d15dc504777f9e7.yaml
+releasenotes/notes/bug-1582774-3bba709ef61e33b7.yaml
+releasenotes/notes/bug-1582968-4d44912a033b242c.yaml
+releasenotes/notes/bug-1584596-5b3109487b451bec.yaml
+releasenotes/notes/bug-1588171-61214d0ea482988c.yaml
+releasenotes/notes/bug-1588384-eb6976fcfb90cb4c.yaml
+releasenotes/notes/bug-1588588-39927ef06ca35730.yaml
+releasenotes/notes/bug-1589332-2941f5286df7e5d4.yaml
+releasenotes/notes/bug-1589348-4a612a4efc7ed0e5.yaml
+releasenotes/notes/bug-1589935-8a56e6a18d836db9.yaml
+releasenotes/notes/bug-1592062-e327a31a5ae66809.yaml
+releasenotes/notes/bug-1592368-a4af69f163a1e208.yaml
+releasenotes/notes/bug-1592761-f45998453d6801f7.yaml
+releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml
+releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml
+releasenotes/notes/bug-1592906-e69b37377278d9c2.yaml
+releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml
+releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml
+releasenotes/notes/bug-1596818-d4cd93dd4d38d3d6.yaml
+releasenotes/notes/bug-1596821-a07599eb4beb6342.yaml
+releasenotes/notes/bug-1597184-f4fb687b3d4d99d9.yaml
+releasenotes/notes/bug-1597188-a2ff62b809865365.yaml
+releasenotes/notes/bug-1597189-02a8d8a402725860.yaml
+releasenotes/notes/bug-1597192-52801f7520287309.yaml
+releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml
+releasenotes/notes/bug-1597198-e36b55f3fd185a3a.yaml
+releasenotes/notes/bug-1597296-9735f33eacf5552e.yaml
+releasenotes/notes/bug-1600196-6a733dd4e3371df7.yaml
+releasenotes/notes/bug-1602073-5deb58deeafbc8be.yaml
+releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml
+releasenotes/notes/bug-1605088-fea9347336764469.yaml
+releasenotes/notes/bug-1605475-84e649fb8c675737.yaml
+releasenotes/notes/bug-1605774-28aec51f6ec4926e.yaml
+releasenotes/notes/bug-1606105-ca06b230e22ab5c6.yaml
+releasenotes/notes/bug-1607959-a52aa93e3793f28a.yaml
+releasenotes/notes/bug-1607972-a910a9fbdb81da57.yaml
+releasenotes/notes/bug-1609233-90b2ddf8d941050e.yaml
+releasenotes/notes/bug-1609767-0602edc4408c2dc6.yaml
+releasenotes/notes/bug-1610161-7c34c7b735701bd4.yaml
+releasenotes/notes/bug-1610883-38929f6fc2eefc9a.yaml
+releasenotes/notes/bug-1610883-e6345c32a35cc290.yaml
+releasenotes/notes/bug-1612136-051b5f94796e3b51.yaml
+releasenotes/notes/bug-1612136-6111b944569b9351.yaml
+releasenotes/notes/bug-1612136-63aac6377209db38.yaml
+releasenotes/notes/bug-1612136-ec240349a933db12.yaml
+releasenotes/notes/bug-1612484-e8605ad8966a455e.yaml
+releasenotes/notes/bug-1612898-bea3b68251d12d81.yaml
+releasenotes/notes/bug-1613231-386b2b1373662052.yaml
+releasenotes/notes/bug-1613261-290a64080fead6c0.yaml
+releasenotes/notes/bug-1613533-93279179c6f70117.yaml
+releasenotes/notes/bug-1613597-b1545148b0755e6f.yaml
+releasenotes/notes/bug-1613926-2d0e405831c0b5a9.yaml
+releasenotes/notes/bug-1613964-837196399be16b3d.yaml
+releasenotes/notes/bug-1613964-86e0afe0e012a758.yaml
+releasenotes/notes/bug-1613964-b3e8d9d828a3822c.yaml
+releasenotes/notes/bug-1613964-e5760f4825f1e043.yaml
+releasenotes/notes/bug-1613995-10bb3895d702c063.yaml
+releasenotes/notes/bug-1614121-a3c5b6892074d5ae.yaml
+releasenotes/notes/bug-1614379-d8e2815804d53cef.yaml
+releasenotes/notes/bug-1614379-da92ded6d19f5ad5.yaml
+releasenotes/notes/bug-1614385-460b5034ba372463.yaml
+releasenotes/notes/bug-1614458-c42be5738f447db8.yaml
+releasenotes/notes/bug-1614823-e89080342f25f2c0.yaml
+releasenotes/notes/bug-1617384-55c88207115e2a5b.yaml
+releasenotes/notes/bug-1618676-04ff0f335b670567.yaml
+releasenotes/notes/bug-1619274-e78afd7c12ea2c3d.yaml
+releasenotes/notes/bug-1620922-7f27942dc00f7108.yaml
+releasenotes/notes/bug-1622565-2e715aff8b054401.yaml
+releasenotes/notes/bug-1624085-7cf296649277f405.yaml
+releasenotes/notes/bug-1627555-3b47eba215e35b3c.yaml
+releasenotes/notes/bug-1627913-2adf4182977e5926.yaml
+releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml
+releasenotes/notes/bug-1631471-beb0a1c9b4a932cb.yaml
+releasenotes/notes/bug-1633582-df2bee534c2da7fc.yaml
+releasenotes/notes/bug-1634333-a2b04d33ca39440e.yaml
+releasenotes/notes/bug-1634672-7ce577f3adc34eed.yaml
+releasenotes/notes/bug-1634799-1322227c9b0188ca.yaml
+releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml
+releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml
+releasenotes/notes/bug-1637074-1b0e409f30f715ca.yaml
+releasenotes/notes/bug-1637365-b90cdcc05ffc7d3a.yaml
+releasenotes/notes/bug-1637945-f361c834381d409c.yaml
+releasenotes/notes/bug-1639231-21823768bd54170a.yaml
+releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml
+releasenotes/notes/bug-1640086-21d7e5f2ce18f53c.yaml
+releasenotes/notes/bug-1641868-97c284e33f944c2d.yaml
+releasenotes/notes/bug-1642030-166b2b28c8adf22e.yaml
+releasenotes/notes/bug-1642238-3032c7fe7f0ce29d.yaml
+releasenotes/notes/bug-1642301-18b08e0cd4b11687.yaml
+releasenotes/notes/bug-1642301-ad04424c80e8fe50.yaml
+releasenotes/notes/bug-1642772-19f53765bef8ee91.yaml
+releasenotes/notes/bug-1643861-b17ad5dfcb4304ff.yaml
+releasenotes/notes/bug-1645252-219bfd50c8f04846.yaml
+releasenotes/notes/bug-1647242-fdc39e564372857b.yaml
+releasenotes/notes/bug-1647406-c936581034a1b6e4.yaml
+releasenotes/notes/bug-1648087-21dfb7250abfdbe9.yaml
+releasenotes/notes/bug-1648307-a2c6d7698e927449.yaml
+releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml
+releasenotes/notes/bug-1650342-22cb88ef37a41872.yaml
+releasenotes/notes/bug-1651117-a1df37e7ea939ba4.yaml
+releasenotes/notes/bug-1652827-f59bbd1b64df958d.yaml
+releasenotes/notes/bug-1654221-a564ab75a6afc332.yaml
+releasenotes/notes/bug-1655445-96c787e3a51226e0.yaml
+releasenotes/notes/bug-1655537-20b0eb676afa278f.yaml
+releasenotes/notes/bug-1656402-88b12760fb2d4ef9.yaml
+releasenotes/notes/bug-1656572-b40303ae50a41000.yaml
+releasenotes/notes/bug-1656767-36a3d4b9fac335c9.yaml
+releasenotes/notes/bug-1656788-2f5bda2205bc0329.yaml
+releasenotes/notes/bug-1657956-977a615f01775288.yaml
+releasenotes/notes/bug-1658147-9de9ae222f9db9ae.yaml
+releasenotes/notes/bug-1658189-d2b390ad74c96c79.yaml
+releasenotes/notes/bug-1658582-80a76f6b0af0ca12.yaml
+releasenotes/notes/bug-1658614-f84a8cece6f2ef8c.yaml
+releasenotes/notes/bug-1659878-f6a55b7166d99ca8.yaml
+releasenotes/notes/bug-1659894-4518b10615498ba9.yaml
+releasenotes/notes/bug-1659967-644a8ee3621c9e81.yaml
+releasenotes/notes/bug-1659993-a5fe43bef587e490.yaml
+releasenotes/notes/bug-1661814-1692e68a1d2d9770.yaml
+releasenotes/notes/bug-1663520-d880bfa51ca7b798.yaml
+releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml
+releasenotes/notes/bug-1665231-3df6d090d137fe4f.yaml
+releasenotes/notes/bug-1666780-c10010e9061689d3.yaml
+releasenotes/notes/bug-1667266-6497727abc2af9a5.yaml
+releasenotes/notes/bug-1667294-f92efa49627eb00a.yaml
+releasenotes/notes/bug-1667699-6dad786b128ca8b5.yaml
+releasenotes/notes/bug-1670707-c4799fbed39ef75b.yaml
+releasenotes/notes/bug-1672634-ef754cb5109dd0f2.yaml
+releasenotes/notes/bug-1675489-a1d226f2ee911420.yaml
+releasenotes/notes/bug-1677236-7de9d11c3f0fb5ed.yaml
+releasenotes/notes/bug-1684989-3bda158a822d2f73.yaml
+releasenotes/notes/bug-1687814-743ad8418923d5e3.yaml
+releasenotes/notes/bug-1688194-bb008b65267a1169.yaml
+releasenotes/notes/bug-1689233-c3f98e159c75374e.yaml
+releasenotes/notes/bug-1696111-e2cf9233fa872eb7.yaml
+releasenotes/notes/bug-1698390-0df8f0ec4fe354de.yaml
+releasenotes/notes/bug-1698742-66d9d4e6c7ad274a.yaml
+releasenotes/notes/bug-1703278-5e45a92e43552dec.yaml
+releasenotes/notes/bug-1704097-8ff1ce1444b81b04.yaml
+releasenotes/notes/bug-1708570-bb19e1213e887723.yaml
+releasenotes/notes/bug-1711301-472b577f074edd43.yaml
+releasenotes/notes/bug-1712242-934bbe2f2378f5bd.yaml
+releasenotes/notes/bug-1714878-46806jv2yv13q054.yaml
+releasenotes/notes/bug-1716789-abfae897b7e61246.yaml
+releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml
+releasenotes/notes/bug-1717829-c1de1d777d3abaf9.yaml
+releasenotes/notes/bug-1719413-0401d05c91cc9094.yaml
+releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml
+releasenotes/notes/bug-1728525-2c40f0c19adbd0e8.yaml
+releasenotes/notes/bug-1731848-71d0a5fdb1a34a8b.yaml
+releasenotes/notes/bug-1732216-b41bfedebff911e1.yaml
+releasenotes/notes/bug-1732938-e4d91732ef777f9a.yaml
+releasenotes/notes/bug-1735836-9be6d777a6e6410b.yaml
+releasenotes/notes/bug-1740232-91ad72c2ac165f35.yaml
+releasenotes/notes/bug-1741223-7a5c5b6e7f232628.yaml
+releasenotes/notes/bug-1742453-ae4be6de90a3ae1d.yaml
+releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml
+releasenotes/notes/bug-1750983-420945d6c0afb509.yaml
+releasenotes/notes/bug-1750985-a5345f715a14825c.yaml
+releasenotes/notes/bug-1751104-compute-api-2.47-4bfa21cfaa13f408.yaml
+releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml
+releasenotes/notes/bug-1777153-750e6044aa28d5d8.yaml
+releasenotes/notes/bug-1784879-9b632174d4af853f.yaml
+releasenotes/notes/bug-1798744-5512256baf4dc633.yaml
+releasenotes/notes/bug-1827844-8f1de120087c6a22.yaml
+releasenotes/notes/bug-1946816-7665858605453578.yaml
+releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
+releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml
+releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml
+releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml
+releasenotes/notes/bug-2007489-42e41b14e42128ce.yaml
+releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml
+releasenotes/notes/bug-2010376-e15362bdd6c8d6ec.yaml
+releasenotes/notes/bug-2084580-cb1e8c47501e730c.yaml
+releasenotes/notes/bug-27882-402ced7ffe930058.yaml
+releasenotes/notes/bug-volume-list-with-project-2dc867c5e8346a66.yaml
+releasenotes/notes/change-098377fd53cce7a0.yaml
+releasenotes/notes/check-limit-quota-cc7f291dd1b537c1.yaml
+releasenotes/notes/cliff-2.3.0-7ead18fae9ceea80.yaml
+releasenotes/notes/complete_image_switch-203e0b3105a54674.yaml
+releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml
+releasenotes/notes/compute-agent-deff48988e81b30e.yaml
+releasenotes/notes/compute-service-list-forced-down-2b16d1cb44f71a08.yaml
+releasenotes/notes/config-show-00512dc60882e5c0.yaml
+releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml
+releasenotes/notes/consistency-group-create-opts-aliases-e1c2f1498e9b1d3d.yaml
+releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml
+releasenotes/notes/deprecate-volume-group-create-positional-arguments-89f6b886c0f1f2b5.yaml
+releasenotes/notes/deprecated-quota-class-options-ba33a45caedbdf3e.yaml
+releasenotes/notes/deprecated-server-create-file-option-80246b13bd3c1b43.yaml
+releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml
+releasenotes/notes/drop-py2-421c90fbdf18dbc2.yaml
+releasenotes/notes/drop-python-38-9dcbd2b2b51f24f2.yaml
+releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml
+releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml
+releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml
+releasenotes/notes/fix-backup-incremental-d1c1e6886cf32256.yaml
+releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+releasenotes/notes/fix-flavor-props-formatting-d21e97745543caa7.yaml
+releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml
+releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml
+releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml
+releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml
+releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml
+releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml
+releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml
+releasenotes/notes/flavor-create-with-project-19d41bfa93e3c6d0.yaml
+releasenotes/notes/flavor-list-min-disk-min-ram-65ba35e7acc24134.yaml
+releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml
+releasenotes/notes/floating-ip-set-unset-port-28e33875937b69cf.yaml
+releasenotes/notes/floatingip_dns_integration-f26c7575694d098d.yaml
+releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml
+releasenotes/notes/idp-auth-ttl-6632df5db65a3bdd.yaml
+releasenotes/notes/image-import-d5da3e5ce8733fb0.yaml
+releasenotes/notes/image-list-filter-multiple-properties-03c51d43131ee3b6.yaml
+releasenotes/notes/image-list-multiple-tags-a394799c7807f031.yaml
+releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml
+releasenotes/notes/image-set-to-update-image-membership-68221f226ca3b6e0.yaml
+releasenotes/notes/image-stage-ac19c47e6a52ffeb.yaml
+releasenotes/notes/image_set_visibility-babf4ff2f687d465.yaml
+releasenotes/notes/implement-system-scope-4c3c47996f98deac.yaml
+releasenotes/notes/implements-hide-image-4c726a61c336ebaa.yaml
+releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml
+releasenotes/notes/ip-availability-ca1cf440f6c70afc.yaml
+releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
+releasenotes/notes/keypair-create-client-side-generation-73d8dd36192f70c9.yaml
+releasenotes/notes/keypair-support-type-6f7c32aab3b61f7b.yaml
+releasenotes/notes/keypair-user-id-db694210695a0ee0.yaml
+releasenotes/notes/keystone-endpoint-filter-e930a7b72276fa2c.yaml
+releasenotes/notes/keystone-endpoint-group-0c55debbb66844f2.yaml
+releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml
+releasenotes/notes/list-subnet-by-pool-id-a642efc13d04fa08.yaml
+releasenotes/notes/list_role_assignment_names-0db89f50259d4be2.yaml
+releasenotes/notes/list_volume_type_access-f7d9aa6159f757ea.yaml
+releasenotes/notes/make-snapshot-and-backup-name-optional-01971d33640ef1c8.yaml
+releasenotes/notes/migrate-access-rule-to-sdk-923682b4c71fea8a.yaml
+releasenotes/notes/migrate-add-fixed-ip-to-sdk-3d932d77633bc765.yaml
+releasenotes/notes/migrate-agent-commands-1c50ffcb75f91418.yaml
+releasenotes/notes/migrate-application-credential-to-sdk-c79d8dfc3c8e1d9f.yaml
+releasenotes/notes/migrate-backup-commands-0becc8f18cf9737b.yaml
+releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml
+releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml
+releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml
+releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml
+releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml
+releasenotes/notes/migrate-host-list-show-to-sdk-9b80cd9b4196ab01.yaml
+releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml
+releasenotes/notes/migrate-limits-show-f586c9762dfd7d0c.yaml
+releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml
+releasenotes/notes/migrate-resource-filter-commands-2a353edb965723d1.yaml
+releasenotes/notes/migrate-role-assignment-to-sdk-e6e52bef467b4e4c.yaml
+releasenotes/notes/migrate-server-add-network-add-port-to-sdk-7d81b25f59cfbec9.yaml
+releasenotes/notes/migrate-server-add-volume-to-sdk-685e036a88839651.yaml
+releasenotes/notes/migrate-server-backup-to-sdk-0f170baf38e98b40.yaml
+releasenotes/notes/migrate-server-evacuate-to-sdk-a0415988ef5451b2.yaml
+releasenotes/notes/migrate-server-events-to-sdk-6a1f5dce582df245.yaml
+releasenotes/notes/migrate-server-pause-unpause-to-sdk-d74ec8536b764af6.yaml
+releasenotes/notes/migrate-server-reboot-to-sdk-a49822810def4c8a.yaml
+releasenotes/notes/migrate-server-restore-to-sdk-4540f26753031779.yaml
+releasenotes/notes/migrate-server-set-unset-to-sdk-ae32ebcced845b06.yaml
+releasenotes/notes/migrate-server-shelve-unshelve-to-sdk-8fce77586aa68a51.yaml
+releasenotes/notes/migrate-server-start-stop-to-sdk-55edd4e1ff5e6ac7.yaml
+releasenotes/notes/migrate-server-suspend-resume-to-sdk-fd1709336607b496.yaml
+releasenotes/notes/migrate-server-volume-list-update-to-sdk-95b1d3063e46f813.yaml
+releasenotes/notes/migrate-service-list-delete-set-to-sdk-920cbe0d210af565.yaml
+releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml
+releasenotes/notes/migrate-service-to-sdk-6ff62ebf7e41db7c.yaml
+releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml
+releasenotes/notes/migrate-volume-attachment-commands-4309409bca1ca5d4.yaml
+releasenotes/notes/migrate-volume-backend-commands-259e553e213c71b0.yaml
+releasenotes/notes/migrate-volume-revert-to-sdk-1e399853d80ba5f8.yaml
+releasenotes/notes/migrate-volume-summary-to-sdk-96ff58f653e0feaa.yaml
+releasenotes/notes/modify-compute-agent-set-77ff894ef62ebbc7.yaml
+releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml
+releasenotes/notes/network-add-qos-policy-a25e868e67142f90.yaml
+releasenotes/notes/network-flavor-command-support-afe3a9da962a09bf.yaml
+releasenotes/notes/network-ndp-proxy-cli-19afc530fc7061e2.yaml
+releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml
+releasenotes/notes/network-port-create-vnic-type-vdpa-fc02516cfb919941.yaml
+releasenotes/notes/network-qos-rule-type-filters-47f4911a02011501.yaml
+releasenotes/notes/network-quota-no-force-default-0975bdf15655070c.yaml
+releasenotes/notes/network_dns_integration-5914b2c2be474a41.yaml
+releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml
+releasenotes/notes/neutron_mtu-d87e53e2d76f8612.yaml
+releasenotes/notes/no-force-limit-quota-cc7f291dd1b537c1.yaml
+releasenotes/notes/no-project-usage-list-e88eb49aa2e96cf7.yaml
+releasenotes/notes/nova-gaps-server-list-to-sdk-88c8bfc10a9e3032.yaml
+releasenotes/notes/object-stdout-db76cc500948b0e8.yaml
+releasenotes/notes/optional-volume-name-ffbefe463a598b6c.yaml
+releasenotes/notes/options-create-router-97910a882b604652.yaml
+releasenotes/notes/osc-included-image-signing-a7021a4dbdcf6336.yaml
+releasenotes/notes/osc4-compute-09246008eff260cb.yaml
+releasenotes/notes/osc4-identity-6564257c67d43106.yaml
+releasenotes/notes/osc4-image-e922ee6f8e028648.yaml
+releasenotes/notes/osc4-network-db2aed696d964ca6.yaml
+releasenotes/notes/osc4-volume-470422e5a453310e.yaml
+releasenotes/notes/pass_ssh_args-cf26a2ce26ccddaf.yaml
+releasenotes/notes/port-device-profile-4a3bf800da21c778.yaml
+releasenotes/notes/port-list-security-group-4af5d2e789174ff9.yaml
+releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml
+releasenotes/notes/project-cleanup-skip-resource-option-4f80db0d8cf36fdb.yaml
+releasenotes/notes/properties-with-image-property-field.yaml-c51bf37c3106d6ff.yaml
+releasenotes/notes/qos-min-pps-rule-bfe22cea1966c4a0.yaml
+releasenotes/notes/quota-delete-947df66ae5341cbf.yaml
+releasenotes/notes/quota-network-force-920913981b45ba1a.yaml
+releasenotes/notes/quota-set-default-option-bc26d37dc150533b.yaml
+releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml
+releasenotes/notes/quota-show-usage-option-19b1f59fb5f3498f.yaml
+releasenotes/notes/rbac-add-address-group-f9bb83238b5a7c1f.yaml
+releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml
+releasenotes/notes/rbac-add-security-group-35370701a06ac906.yaml
+releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml
+releasenotes/notes/recursive-container-delete-983361aa9c35ffed.yaml
+releasenotes/notes/remove-deprecated-quota-show-class-option-2109a6ff7ac18e80.yaml
+releasenotes/notes/remove-deprecated-server-migrate-live-option-28ec43ee210124dc.yaml
+releasenotes/notes/remove-ip-floating-commands-d5363f313e09249a.yaml
+releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml
+releasenotes/notes/remove-osc_password-0767ac78267ef114.yaml
+releasenotes/notes/remove-project-purge-d372374b1a7c4641.yaml
+releasenotes/notes/remove-unsupported-set-vlan-transparent-eeff412264ae7c09.yaml
+releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml
+releasenotes/notes/rename-server-migrate-confirm-revert-commands-84fcb937721f5c4a.yaml
+releasenotes/notes/rename-server-volume-update-to-server-volume-set-833f1730a9bf6169.yaml
+releasenotes/notes/rename-snapshot-commands-e0937f7143a4ef55.yaml
+releasenotes/notes/rename-volume-set-retype-policy-6bacb7dd92f1ad82.yaml
+releasenotes/notes/restore-create-image-duplicates-92e06f64038b120c.yaml
+releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml
+releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml
+releasenotes/notes/router-gateway-IP-QoS-c8ba95e180bca05f.yaml
+releasenotes/notes/router-gateway-set-01d9c7ffe4461daf.yaml
+releasenotes/notes/router-port-add-0afe7392c080bcb8.yaml
+releasenotes/notes/router-remove-port-058078c93819b0f4.yaml
+releasenotes/notes/router-subnet-469d095ae0bac884.yaml
+releasenotes/notes/security-grp-json-fix.yaml-2af1f48a48034d64.yaml
+releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml
+releasenotes/notes/server-changes-3962541b6ebdbbd8.yaml
+releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml
+releasenotes/notes/server-create-server-group-a5b630f2a64de28d.yaml
+releasenotes/notes/server-description-ae9618fc09544cac.yaml
+releasenotes/notes/server-group-create_rule_option-9f84e52f35e7c3ba.yaml
+releasenotes/notes/server-list-host-status-1f542a5bc4292a62.yaml
+releasenotes/notes/server-list-restrict-images-c0b2c4de6f93df33.yaml
+releasenotes/notes/server-list-selectable-fields.yaml-1d5fb4784fa6f232.yaml
+releasenotes/notes/server-migration-by-uuid-59f8272f63abee5d.yaml
+releasenotes/notes/server-ops-all-projects-2ce2202cdf617184.yaml
+releasenotes/notes/server-rebuild-property-e8c6439b04e27c80.yaml
+releasenotes/notes/server-rebuild-with-keypair-name-83c1aa20db136d91.yaml
+releasenotes/notes/server-set-state-214b12ec2161de4d.yaml
+releasenotes/notes/service-set-option-61772a8940ad0778.yaml
+releasenotes/notes/show-result-for-server-add-volume-f75277ad58e31024.yaml
+releasenotes/notes/show-server-topology-microversion-v2_78-3891fc67f767177e.yaml
+releasenotes/notes/skip-name-lookups-9f499927173c1eee.yaml
+releasenotes/notes/speedup-object-save-6bd59e678a31c3e8.yaml
+releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml
+releasenotes/notes/story-2004346-add-floating-ip-with-no-ports-399c5559e1699816.yaml
+releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml
+releasenotes/notes/story-2005468-server-use-config-drive-9fc68552365cfefa.yaml
+releasenotes/notes/story-2006302-add-boot-from-volume-cd411b1ca776bb3c.yaml
+releasenotes/notes/story-2006302-support-bdm-type-image-0becfb63bd4fb969.yaml
+releasenotes/notes/story-2007727-69b705c561309742.yaml
+releasenotes/notes/story-2010343-b5eb4ed593f51d3f.yaml
+releasenotes/notes/story-2010751-server-rebuild-wait-shutoff-c84cddcd3f15e9ce.yaml
+releasenotes/notes/subnet-service-type-8d9c414732e474a4.yaml
+releasenotes/notes/subnet-set-bbc26ecc16929302.yaml
+releasenotes/notes/subnet-set-segment-id-4440e433b170f9f3.yaml
+releasenotes/notes/subnet-unset-5b458cdbaf93d766.yaml
+releasenotes/notes/subnet-unset-gateway-20239d5910e10778.yaml
+releasenotes/notes/support-icmp-type-code-zero-cbef0a36db2b8123.yaml
+releasenotes/notes/support-no-property-in-volume-811e67ff4a199eb6.yaml
+releasenotes/notes/support-no-property-in-volume-snapshot-0af3fcb31a3cfc2b.yaml
+releasenotes/notes/support-uplink_status_propagation-4d37452bcf03e0f8.yaml
+releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml
+releasenotes/notes/switch-console-log-to-sdk-6ee92b7833364d3d.yaml
+releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml
+releasenotes/notes/switch-hypervisor-to-sdk-2e90b26a14ffcef3.yaml
+releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml
+releasenotes/notes/switch-keypair-to-sdk-81e28380e66a7f9c.yaml
+releasenotes/notes/switch-server-lock-to-sdk-d5dd17e4987233a5.yaml
+releasenotes/notes/switch-server-migration-show-to-sdk-4adb88a0f1f03f3b.yaml
+releasenotes/notes/switch-server-migration-to-sdk-4e4530f787f90fd2.yaml
+releasenotes/notes/switch-server-remove-network-port-to-sdk-829ba711e0e198d5.yaml
+releasenotes/notes/switch-server-remove-volume-to-sdk-47e9befd2672dcdf.yaml
+releasenotes/notes/switch-server-show-to-sdk-44a614aebf2c6da6.yaml
+releasenotes/notes/task-40279-eb0d718ac1959c50.yaml
+releasenotes/notes/unlock-volume-a6990fc3bf1f5f67.yaml
+releasenotes/notes/unset-router-7b0cbd9518bb1de6.yaml
+releasenotes/notes/unset-subnet-pool-333052dd85b95653.yaml
+releasenotes/notes/usage-list-all-49ca7a62c50e71d3.yaml
+releasenotes/notes/use_sdk_for_image-f49d2df38e7d9f81.yaml
+releasenotes/notes/versions-show-12a2443624c83048.yaml
+releasenotes/notes/volume-attachment-create-output-fix-56515b8fcdd260b9.yaml
+releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
+releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml
+releasenotes/notes/volume-backup-record-9f5987c45e294dc6.yaml
+releasenotes/notes/volume-migrate-command-52cf6edd62fe17a7.yaml
+releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml
+releasenotes/notes/volume-type-list-properties-filter-8532f96d16733915.yaml
+releasenotes/notes/volume-v3-default-0ffa9bebb43b5057.yaml
+releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml
+releasenotes/notes/warn-on-disk-overcommit-087ae46f12d74693.yaml
+releasenotes/source/2023.1.rst
+releasenotes/source/2023.2.rst
+releasenotes/source/2024.1.rst
+releasenotes/source/2024.2.rst
+releasenotes/source/2025.1.rst
+releasenotes/source/20_releases.rst
+releasenotes/source/conf.py
+releasenotes/source/index.rst
+releasenotes/source/mitaka.rst
+releasenotes/source/newton.rst
+releasenotes/source/ocata.rst
+releasenotes/source/pike.rst
+releasenotes/source/pre_20_releases.rst
+releasenotes/source/queens.rst
+releasenotes/source/rocky.rst
+releasenotes/source/stein.rst
+releasenotes/source/train.rst
+releasenotes/source/unreleased.rst
+releasenotes/source/ussuri.rst
+releasenotes/source/victoria.rst
+releasenotes/source/wallaby.rst
+releasenotes/source/xena.rst
+releasenotes/source/yoga.rst
+releasenotes/source/zed.rst
+releasenotes/source/_static/.placeholder
+releasenotes/source/_templates/.placeholder
\ No newline at end of file
diff -pruN 7.4.0-3/python_openstackclient.egg-info/dependency_links.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/dependency_links.txt
--- 7.4.0-3/python_openstackclient.egg-info/dependency_links.txt	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/dependency_links.txt	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1 @@
+
diff -pruN 7.4.0-3/python_openstackclient.egg-info/entry_points.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/entry_points.txt
--- 7.4.0-3/python_openstackclient.egg-info/entry_points.txt	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/entry_points.txt	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1,677 @@
+[console_scripts]
+openstack = openstackclient.shell:main
+
+[openstack.cli]
+command_list = openstackclient.common.module:ListCommand
+module_list = openstackclient.common.module:ListModule
+
+[openstack.cli.base]
+compute = openstackclient.compute.client
+identity = openstackclient.identity.client
+image = openstackclient.image.client
+network = openstackclient.network.client
+object_store = openstackclient.object.client
+volume = openstackclient.volume.client
+
+[openstack.common]
+availability_zone_list = openstackclient.common.availability_zone:ListAvailabilityZone
+configuration_show = openstackclient.common.configuration:ShowConfiguration
+extension_list = openstackclient.common.extension:ListExtension
+extension_show = openstackclient.common.extension:ShowExtension
+limits_show = openstackclient.common.limits:ShowLimits
+project_cleanup = openstackclient.common.project_cleanup:ProjectCleanup
+quota_delete = openstackclient.common.quota:DeleteQuota
+quota_list = openstackclient.common.quota:ListQuota
+quota_set = openstackclient.common.quota:SetQuota
+quota_show = openstackclient.common.quota:ShowQuota
+versions_show = openstackclient.common.versions:ShowVersions
+
+[openstack.compute.v2]
+aggregate_add_host = openstackclient.compute.v2.aggregate:AddAggregateHost
+aggregate_cache_image = openstackclient.compute.v2.aggregate:CacheImageForAggregate
+aggregate_create = openstackclient.compute.v2.aggregate:CreateAggregate
+aggregate_delete = openstackclient.compute.v2.aggregate:DeleteAggregate
+aggregate_list = openstackclient.compute.v2.aggregate:ListAggregate
+aggregate_remove_host = openstackclient.compute.v2.aggregate:RemoveAggregateHost
+aggregate_set = openstackclient.compute.v2.aggregate:SetAggregate
+aggregate_show = openstackclient.compute.v2.aggregate:ShowAggregate
+aggregate_unset = openstackclient.compute.v2.aggregate:UnsetAggregate
+compute_agent_create = openstackclient.compute.v2.agent:CreateAgent
+compute_agent_delete = openstackclient.compute.v2.agent:DeleteAgent
+compute_agent_list = openstackclient.compute.v2.agent:ListAgent
+compute_agent_set = openstackclient.compute.v2.agent:SetAgent
+compute_service_delete = openstackclient.compute.v2.service:DeleteService
+compute_service_list = openstackclient.compute.v2.service:ListService
+compute_service_set = openstackclient.compute.v2.service:SetService
+console_connection_show = openstackclient.compute.v2.console_connection:ShowConsoleConnectionInformation
+console_log_show = openstackclient.compute.v2.console:ShowConsoleLog
+console_url_show = openstackclient.compute.v2.console:ShowConsoleURL
+flavor_create = openstackclient.compute.v2.flavor:CreateFlavor
+flavor_delete = openstackclient.compute.v2.flavor:DeleteFlavor
+flavor_list = openstackclient.compute.v2.flavor:ListFlavor
+flavor_set = openstackclient.compute.v2.flavor:SetFlavor
+flavor_show = openstackclient.compute.v2.flavor:ShowFlavor
+flavor_unset = openstackclient.compute.v2.flavor:UnsetFlavor
+host_list = openstackclient.compute.v2.host:ListHost
+host_set = openstackclient.compute.v2.host:SetHost
+host_show = openstackclient.compute.v2.host:ShowHost
+hypervisor_list = openstackclient.compute.v2.hypervisor:ListHypervisor
+hypervisor_show = openstackclient.compute.v2.hypervisor:ShowHypervisor
+hypervisor_stats_show = openstackclient.compute.v2.hypervisor_stats:ShowHypervisorStats
+keypair_create = openstackclient.compute.v2.keypair:CreateKeypair
+keypair_delete = openstackclient.compute.v2.keypair:DeleteKeypair
+keypair_list = openstackclient.compute.v2.keypair:ListKeypair
+keypair_show = openstackclient.compute.v2.keypair:ShowKeypair
+server_add_fixed_ip = openstackclient.compute.v2.server:AddFixedIP
+server_add_floating_ip = openstackclient.compute.v2.server:AddFloatingIP
+server_add_network = openstackclient.compute.v2.server:AddNetwork
+server_add_port = openstackclient.compute.v2.server:AddPort
+server_add_security_group = openstackclient.compute.v2.server:AddServerSecurityGroup
+server_add_volume = openstackclient.compute.v2.server:AddServerVolume
+server_backup_create = openstackclient.compute.v2.server_backup:CreateServerBackup
+server_create = openstackclient.compute.v2.server:CreateServer
+server_delete = openstackclient.compute.v2.server:DeleteServer
+server_dump_create = openstackclient.compute.v2.server:CreateServerDump
+server_evacuate = openstackclient.compute.v2.server:EvacuateServer
+server_event_list = openstackclient.compute.v2.server_event:ListServerEvent
+server_event_show = openstackclient.compute.v2.server_event:ShowServerEvent
+server_group_create = openstackclient.compute.v2.server_group:CreateServerGroup
+server_group_delete = openstackclient.compute.v2.server_group:DeleteServerGroup
+server_group_list = openstackclient.compute.v2.server_group:ListServerGroup
+server_group_show = openstackclient.compute.v2.server_group:ShowServerGroup
+server_image_create = openstackclient.compute.v2.server_image:CreateServerImage
+server_list = openstackclient.compute.v2.server:ListServer
+server_lock = openstackclient.compute.v2.server:LockServer
+server_migrate = openstackclient.compute.v2.server:MigrateServer
+server_migrate_confirm = openstackclient.compute.v2.server:MigrateConfirm
+server_migrate_revert = openstackclient.compute.v2.server:MigrateRevert
+server_migration_abort = openstackclient.compute.v2.server_migration:AbortMigration
+server_migration_confirm = openstackclient.compute.v2.server:ConfirmMigration
+server_migration_force_complete = openstackclient.compute.v2.server_migration:ForceCompleteMigration
+server_migration_list = openstackclient.compute.v2.server_migration:ListMigration
+server_migration_revert = openstackclient.compute.v2.server:RevertMigration
+server_migration_show = openstackclient.compute.v2.server_migration:ShowMigration
+server_pause = openstackclient.compute.v2.server:PauseServer
+server_reboot = openstackclient.compute.v2.server:RebootServer
+server_rebuild = openstackclient.compute.v2.server:RebuildServer
+server_remove_fixed_ip = openstackclient.compute.v2.server:RemoveFixedIP
+server_remove_floating_ip = openstackclient.compute.v2.server:RemoveFloatingIP
+server_remove_network = openstackclient.compute.v2.server:RemoveNetwork
+server_remove_port = openstackclient.compute.v2.server:RemovePort
+server_remove_security_group = openstackclient.compute.v2.server:RemoveServerSecurityGroup
+server_remove_volume = openstackclient.compute.v2.server:RemoveServerVolume
+server_rescue = openstackclient.compute.v2.server:RescueServer
+server_resize = openstackclient.compute.v2.server:ResizeServer
+server_resize_confirm = openstackclient.compute.v2.server:ResizeConfirm
+server_resize_revert = openstackclient.compute.v2.server:ResizeRevert
+server_restore = openstackclient.compute.v2.server:RestoreServer
+server_resume = openstackclient.compute.v2.server:ResumeServer
+server_set = openstackclient.compute.v2.server:SetServer
+server_shelve = openstackclient.compute.v2.server:ShelveServer
+server_show = openstackclient.compute.v2.server:ShowServer
+server_ssh = openstackclient.compute.v2.server:SshServer
+server_start = openstackclient.compute.v2.server:StartServer
+server_stop = openstackclient.compute.v2.server:StopServer
+server_suspend = openstackclient.compute.v2.server:SuspendServer
+server_unlock = openstackclient.compute.v2.server:UnlockServer
+server_unpause = openstackclient.compute.v2.server:UnpauseServer
+server_unrescue = openstackclient.compute.v2.server:UnrescueServer
+server_unset = openstackclient.compute.v2.server:UnsetServer
+server_unshelve = openstackclient.compute.v2.server:UnshelveServer
+server_volume_list = openstackclient.compute.v2.server_volume:ListServerVolume
+server_volume_set = openstackclient.compute.v2.server_volume:SetServerVolume
+server_volume_update = openstackclient.compute.v2.server_volume:UpdateServerVolume
+usage_list = openstackclient.compute.v2.usage:ListUsage
+usage_show = openstackclient.compute.v2.usage:ShowUsage
+
+[openstack.identity.v2]
+catalog_list = openstackclient.identity.v2_0.catalog:ListCatalog
+catalog_show = openstackclient.identity.v2_0.catalog:ShowCatalog
+ec2_credentials_create = openstackclient.identity.v2_0.ec2creds:CreateEC2Creds
+ec2_credentials_delete = openstackclient.identity.v2_0.ec2creds:DeleteEC2Creds
+ec2_credentials_list = openstackclient.identity.v2_0.ec2creds:ListEC2Creds
+ec2_credentials_show = openstackclient.identity.v2_0.ec2creds:ShowEC2Creds
+endpoint_create = openstackclient.identity.v2_0.endpoint:CreateEndpoint
+endpoint_delete = openstackclient.identity.v2_0.endpoint:DeleteEndpoint
+endpoint_list = openstackclient.identity.v2_0.endpoint:ListEndpoint
+endpoint_show = openstackclient.identity.v2_0.endpoint:ShowEndpoint
+project_create = openstackclient.identity.v2_0.project:CreateProject
+project_delete = openstackclient.identity.v2_0.project:DeleteProject
+project_list = openstackclient.identity.v2_0.project:ListProject
+project_set = openstackclient.identity.v2_0.project:SetProject
+project_show = openstackclient.identity.v2_0.project:ShowProject
+project_unset = openstackclient.identity.v2_0.project:UnsetProject
+role_add = openstackclient.identity.v2_0.role:AddRole
+role_assignment_list = openstackclient.identity.v2_0.role_assignment:ListRoleAssignment
+role_create = openstackclient.identity.v2_0.role:CreateRole
+role_delete = openstackclient.identity.v2_0.role:DeleteRole
+role_list = openstackclient.identity.v2_0.role:ListRole
+role_remove = openstackclient.identity.v2_0.role:RemoveRole
+role_show = openstackclient.identity.v2_0.role:ShowRole
+service_create = openstackclient.identity.v2_0.service:CreateService
+service_delete = openstackclient.identity.v2_0.service:DeleteService
+service_list = openstackclient.identity.v2_0.service:ListService
+service_show = openstackclient.identity.v2_0.service:ShowService
+token_issue = openstackclient.identity.v2_0.token:IssueToken
+token_revoke = openstackclient.identity.v2_0.token:RevokeToken
+user_create = openstackclient.identity.v2_0.user:CreateUser
+user_delete = openstackclient.identity.v2_0.user:DeleteUser
+user_list = openstackclient.identity.v2_0.user:ListUser
+user_set = openstackclient.identity.v2_0.user:SetUser
+user_show = openstackclient.identity.v2_0.user:ShowUser
+
+[openstack.identity.v3]
+access_rule_delete = openstackclient.identity.v3.access_rule:DeleteAccessRule
+access_rule_list = openstackclient.identity.v3.access_rule:ListAccessRule
+access_rule_show = openstackclient.identity.v3.access_rule:ShowAccessRule
+access_token_create = openstackclient.identity.v3.token:CreateAccessToken
+application_credential_create = openstackclient.identity.v3.application_credential:CreateApplicationCredential
+application_credential_delete = openstackclient.identity.v3.application_credential:DeleteApplicationCredential
+application_credential_list = openstackclient.identity.v3.application_credential:ListApplicationCredential
+application_credential_show = openstackclient.identity.v3.application_credential:ShowApplicationCredential
+catalog_list = openstackclient.identity.v3.catalog:ListCatalog
+catalog_show = openstackclient.identity.v3.catalog:ShowCatalog
+consumer_create = openstackclient.identity.v3.consumer:CreateConsumer
+consumer_delete = openstackclient.identity.v3.consumer:DeleteConsumer
+consumer_list = openstackclient.identity.v3.consumer:ListConsumer
+consumer_set = openstackclient.identity.v3.consumer:SetConsumer
+consumer_show = openstackclient.identity.v3.consumer:ShowConsumer
+credential_create = openstackclient.identity.v3.credential:CreateCredential
+credential_delete = openstackclient.identity.v3.credential:DeleteCredential
+credential_list = openstackclient.identity.v3.credential:ListCredential
+credential_set = openstackclient.identity.v3.credential:SetCredential
+credential_show = openstackclient.identity.v3.credential:ShowCredential
+domain_create = openstackclient.identity.v3.domain:CreateDomain
+domain_delete = openstackclient.identity.v3.domain:DeleteDomain
+domain_list = openstackclient.identity.v3.domain:ListDomain
+domain_set = openstackclient.identity.v3.domain:SetDomain
+domain_show = openstackclient.identity.v3.domain:ShowDomain
+ec2_credentials_create = openstackclient.identity.v3.ec2creds:CreateEC2Creds
+ec2_credentials_delete = openstackclient.identity.v3.ec2creds:DeleteEC2Creds
+ec2_credentials_list = openstackclient.identity.v3.ec2creds:ListEC2Creds
+ec2_credentials_show = openstackclient.identity.v3.ec2creds:ShowEC2Creds
+endpoint_add_project = openstackclient.identity.v3.endpoint:AddProjectToEndpoint
+endpoint_create = openstackclient.identity.v3.endpoint:CreateEndpoint
+endpoint_delete = openstackclient.identity.v3.endpoint:DeleteEndpoint
+endpoint_group_add_project = openstackclient.identity.v3.endpoint_group:AddProjectToEndpointGroup
+endpoint_group_create = openstackclient.identity.v3.endpoint_group:CreateEndpointGroup
+endpoint_group_delete = openstackclient.identity.v3.endpoint_group:DeleteEndpointGroup
+endpoint_group_list = openstackclient.identity.v3.endpoint_group:ListEndpointGroup
+endpoint_group_remove_project = openstackclient.identity.v3.endpoint_group:RemoveProjectFromEndpointGroup
+endpoint_group_set = openstackclient.identity.v3.endpoint_group:SetEndpointGroup
+endpoint_group_show = openstackclient.identity.v3.endpoint_group:ShowEndpointGroup
+endpoint_list = openstackclient.identity.v3.endpoint:ListEndpoint
+endpoint_remove_project = openstackclient.identity.v3.endpoint:RemoveProjectFromEndpoint
+endpoint_set = openstackclient.identity.v3.endpoint:SetEndpoint
+endpoint_show = openstackclient.identity.v3.endpoint:ShowEndpoint
+federation_domain_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleDomains
+federation_project_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleProjects
+federation_protocol_create = openstackclient.identity.v3.federation_protocol:CreateProtocol
+federation_protocol_delete = openstackclient.identity.v3.federation_protocol:DeleteProtocol
+federation_protocol_list = openstackclient.identity.v3.federation_protocol:ListProtocols
+federation_protocol_set = openstackclient.identity.v3.federation_protocol:SetProtocol
+federation_protocol_show = openstackclient.identity.v3.federation_protocol:ShowProtocol
+group_add_user = openstackclient.identity.v3.group:AddUserToGroup
+group_contains_user = openstackclient.identity.v3.group:CheckUserInGroup
+group_create = openstackclient.identity.v3.group:CreateGroup
+group_delete = openstackclient.identity.v3.group:DeleteGroup
+group_list = openstackclient.identity.v3.group:ListGroup
+group_remove_user = openstackclient.identity.v3.group:RemoveUserFromGroup
+group_set = openstackclient.identity.v3.group:SetGroup
+group_show = openstackclient.identity.v3.group:ShowGroup
+identity_provider_create = openstackclient.identity.v3.identity_provider:CreateIdentityProvider
+identity_provider_delete = openstackclient.identity.v3.identity_provider:DeleteIdentityProvider
+identity_provider_list = openstackclient.identity.v3.identity_provider:ListIdentityProvider
+identity_provider_set = openstackclient.identity.v3.identity_provider:SetIdentityProvider
+identity_provider_show = openstackclient.identity.v3.identity_provider:ShowIdentityProvider
+implied_role_create = openstackclient.identity.v3.implied_role:CreateImpliedRole
+implied_role_delete = openstackclient.identity.v3.implied_role:DeleteImpliedRole
+implied_role_list = openstackclient.identity.v3.implied_role:ListImpliedRole
+limit_create = openstackclient.identity.v3.limit:CreateLimit
+limit_delete = openstackclient.identity.v3.limit:DeleteLimit
+limit_list = openstackclient.identity.v3.limit:ListLimit
+limit_set = openstackclient.identity.v3.limit:SetLimit
+limit_show = openstackclient.identity.v3.limit:ShowLimit
+mapping_create = openstackclient.identity.v3.mapping:CreateMapping
+mapping_delete = openstackclient.identity.v3.mapping:DeleteMapping
+mapping_list = openstackclient.identity.v3.mapping:ListMapping
+mapping_set = openstackclient.identity.v3.mapping:SetMapping
+mapping_show = openstackclient.identity.v3.mapping:ShowMapping
+policy_create = openstackclient.identity.v3.policy:CreatePolicy
+policy_delete = openstackclient.identity.v3.policy:DeletePolicy
+policy_list = openstackclient.identity.v3.policy:ListPolicy
+policy_set = openstackclient.identity.v3.policy:SetPolicy
+policy_show = openstackclient.identity.v3.policy:ShowPolicy
+project_create = openstackclient.identity.v3.project:CreateProject
+project_delete = openstackclient.identity.v3.project:DeleteProject
+project_list = openstackclient.identity.v3.project:ListProject
+project_set = openstackclient.identity.v3.project:SetProject
+project_show = openstackclient.identity.v3.project:ShowProject
+region_create = openstackclient.identity.v3.region:CreateRegion
+region_delete = openstackclient.identity.v3.region:DeleteRegion
+region_list = openstackclient.identity.v3.region:ListRegion
+region_set = openstackclient.identity.v3.region:SetRegion
+region_show = openstackclient.identity.v3.region:ShowRegion
+registered_limit_create = openstackclient.identity.v3.registered_limit:CreateRegisteredLimit
+registered_limit_delete = openstackclient.identity.v3.registered_limit:DeleteRegisteredLimit
+registered_limit_list = openstackclient.identity.v3.registered_limit:ListRegisteredLimit
+registered_limit_set = openstackclient.identity.v3.registered_limit:SetRegisteredLimit
+registered_limit_show = openstackclient.identity.v3.registered_limit:ShowRegisteredLimit
+request_token_authorize = openstackclient.identity.v3.token:AuthorizeRequestToken
+request_token_create = openstackclient.identity.v3.token:CreateRequestToken
+role_add = openstackclient.identity.v3.role:AddRole
+role_assignment_list = openstackclient.identity.v3.role_assignment:ListRoleAssignment
+role_create = openstackclient.identity.v3.role:CreateRole
+role_delete = openstackclient.identity.v3.role:DeleteRole
+role_list = openstackclient.identity.v3.role:ListRole
+role_remove = openstackclient.identity.v3.role:RemoveRole
+role_set = openstackclient.identity.v3.role:SetRole
+role_show = openstackclient.identity.v3.role:ShowRole
+service_create = openstackclient.identity.v3.service:CreateService
+service_delete = openstackclient.identity.v3.service:DeleteService
+service_list = openstackclient.identity.v3.service:ListService
+service_provider_create = openstackclient.identity.v3.service_provider:CreateServiceProvider
+service_provider_delete = openstackclient.identity.v3.service_provider:DeleteServiceProvider
+service_provider_list = openstackclient.identity.v3.service_provider:ListServiceProvider
+service_provider_set = openstackclient.identity.v3.service_provider:SetServiceProvider
+service_provider_show = openstackclient.identity.v3.service_provider:ShowServiceProvider
+service_set = openstackclient.identity.v3.service:SetService
+service_show = openstackclient.identity.v3.service:ShowService
+token_issue = openstackclient.identity.v3.token:IssueToken
+token_revoke = openstackclient.identity.v3.token:RevokeToken
+trust_create = openstackclient.identity.v3.trust:CreateTrust
+trust_delete = openstackclient.identity.v3.trust:DeleteTrust
+trust_list = openstackclient.identity.v3.trust:ListTrust
+trust_show = openstackclient.identity.v3.trust:ShowTrust
+user_create = openstackclient.identity.v3.user:CreateUser
+user_delete = openstackclient.identity.v3.user:DeleteUser
+user_list = openstackclient.identity.v3.user:ListUser
+user_password_set = openstackclient.identity.v3.user:SetPasswordUser
+user_set = openstackclient.identity.v3.user:SetUser
+user_show = openstackclient.identity.v3.user:ShowUser
+
+[openstack.image.v1]
+image_create = openstackclient.image.v1.image:CreateImage
+image_delete = openstackclient.image.v1.image:DeleteImage
+image_list = openstackclient.image.v1.image:ListImage
+image_save = openstackclient.image.v1.image:SaveImage
+image_set = openstackclient.image.v1.image:SetImage
+image_show = openstackclient.image.v1.image:ShowImage
+
+[openstack.image.v2]
+cached_image_clear = openstackclient.image.v2.cache:ClearCachedImage
+cached_image_delete = openstackclient.image.v2.cache:DeleteCachedImage
+cached_image_list = openstackclient.image.v2.cache:ListCachedImage
+cached_image_queue = openstackclient.image.v2.cache:QueueCachedImage
+image_add_project = openstackclient.image.v2.image:AddProjectToImage
+image_create = openstackclient.image.v2.image:CreateImage
+image_delete = openstackclient.image.v2.image:DeleteImage
+image_import = openstackclient.image.v2.image:ImportImage
+image_import_info = openstackclient.image.v2.info:ImportInfo
+image_list = openstackclient.image.v2.image:ListImage
+image_member_get = openstackclient.image.v2.image:ShowProjectImage
+image_member_list = openstackclient.image.v2.image:ListImageProjects
+image_metadef_namespace_create = openstackclient.image.v2.metadef_namespaces:CreateMetadefNamespace
+image_metadef_namespace_delete = openstackclient.image.v2.metadef_namespaces:DeleteMetadefNamespace
+image_metadef_namespace_list = openstackclient.image.v2.metadef_namespaces:ListMetadefNamespace
+image_metadef_namespace_set = openstackclient.image.v2.metadef_namespaces:SetMetadefNamespace
+image_metadef_namespace_show = openstackclient.image.v2.metadef_namespaces:ShowMetadefNamespace
+image_metadef_object_create = openstackclient.image.v2.metadef_objects:CreateMetadefObjects
+image_metadef_object_delete = openstackclient.image.v2.metadef_objects:DeleteMetadefObject
+image_metadef_object_list = openstackclient.image.v2.metadef_objects:ListMetadefObjects
+image_metadef_object_property_show = openstackclient.image.v2.metadef_objects:ShowMetadefObjectProperty
+image_metadef_object_show = openstackclient.image.v2.metadef_objects:ShowMetadefObjects
+image_metadef_object_update = openstackclient.image.v2.metadef_objects:SetMetadefObject
+image_metadef_property_create = openstackclient.image.v2.metadef_properties:CreateMetadefProperty
+image_metadef_property_delete = openstackclient.image.v2.metadef_properties:DeleteMetadefProperty
+image_metadef_property_list = openstackclient.image.v2.metadef_properties:ListMetadefProperties
+image_metadef_property_set = openstackclient.image.v2.metadef_properties:SetMetadefProperty
+image_metadef_property_show = openstackclient.image.v2.metadef_properties:ShowMetadefProperty
+image_metadef_resource_type_association_create = openstackclient.image.v2.metadef_resource_type_association:CreateMetadefResourceTypeAssociation
+image_metadef_resource_type_association_delete = openstackclient.image.v2.metadef_resource_type_association:DeleteMetadefResourceTypeAssociation
+image_metadef_resource_type_association_list = openstackclient.image.v2.metadef_resource_type_association:ListMetadefResourceTypeAssociations
+image_metadef_resource_type_list = openstackclient.image.v2.metadef_resource_types:ListMetadefResourceTypes
+image_remove_project = openstackclient.image.v2.image:RemoveProjectImage
+image_save = openstackclient.image.v2.image:SaveImage
+image_set = openstackclient.image.v2.image:SetImage
+image_show = openstackclient.image.v2.image:ShowImage
+image_stage = openstackclient.image.v2.image:StageImage
+image_stores_list = openstackclient.image.v2.image:StoresInfo
+image_task_list = openstackclient.image.v2.task:ListTask
+image_task_show = openstackclient.image.v2.task:ShowTask
+image_unset = openstackclient.image.v2.image:UnsetImage
+
+[openstack.network.v2]
+address_group_create = openstackclient.network.v2.address_group:CreateAddressGroup
+address_group_delete = openstackclient.network.v2.address_group:DeleteAddressGroup
+address_group_list = openstackclient.network.v2.address_group:ListAddressGroup
+address_group_set = openstackclient.network.v2.address_group:SetAddressGroup
+address_group_show = openstackclient.network.v2.address_group:ShowAddressGroup
+address_group_unset = openstackclient.network.v2.address_group:UnsetAddressGroup
+address_scope_create = openstackclient.network.v2.address_scope:CreateAddressScope
+address_scope_delete = openstackclient.network.v2.address_scope:DeleteAddressScope
+address_scope_list = openstackclient.network.v2.address_scope:ListAddressScope
+address_scope_set = openstackclient.network.v2.address_scope:SetAddressScope
+address_scope_show = openstackclient.network.v2.address_scope:ShowAddressScope
+default_security_group_rule_create = openstackclient.network.v2.default_security_group_rule:CreateDefaultSecurityGroupRule
+default_security_group_rule_delete = openstackclient.network.v2.default_security_group_rule:DeleteDefaultSecurityGroupRule
+default_security_group_rule_list = openstackclient.network.v2.default_security_group_rule:ListDefaultSecurityGroupRule
+default_security_group_rule_show = openstackclient.network.v2.default_security_group_rule:ShowDefaultSecurityGroupRule
+floating_ip_create = openstackclient.network.v2.floating_ip:CreateFloatingIP
+floating_ip_delete = openstackclient.network.v2.floating_ip:DeleteFloatingIP
+floating_ip_list = openstackclient.network.v2.floating_ip:ListFloatingIP
+floating_ip_pool_list = openstackclient.network.v2.floating_ip_pool:ListFloatingIPPool
+floating_ip_port_forwarding_create = openstackclient.network.v2.floating_ip_port_forwarding:CreateFloatingIPPortForwarding
+floating_ip_port_forwarding_delete = openstackclient.network.v2.floating_ip_port_forwarding:DeleteFloatingIPPortForwarding
+floating_ip_port_forwarding_list = openstackclient.network.v2.floating_ip_port_forwarding:ListFloatingIPPortForwarding
+floating_ip_port_forwarding_set = openstackclient.network.v2.floating_ip_port_forwarding:SetFloatingIPPortForwarding
+floating_ip_port_forwarding_show = openstackclient.network.v2.floating_ip_port_forwarding:ShowFloatingIPPortForwarding
+floating_ip_set = openstackclient.network.v2.floating_ip:SetFloatingIP
+floating_ip_show = openstackclient.network.v2.floating_ip:ShowFloatingIP
+floating_ip_unset = openstackclient.network.v2.floating_ip:UnsetFloatingIP
+ip_availability_list = openstackclient.network.v2.ip_availability:ListIPAvailability
+ip_availability_show = openstackclient.network.v2.ip_availability:ShowIPAvailability
+local_ip_association_create = openstackclient.network.v2.local_ip_association:CreateLocalIPAssociation
+local_ip_association_delete = openstackclient.network.v2.local_ip_association:DeleteLocalIPAssociation
+local_ip_association_list = openstackclient.network.v2.local_ip_association:ListLocalIPAssociation
+local_ip_create = openstackclient.network.v2.local_ip:CreateLocalIP
+local_ip_delete = openstackclient.network.v2.local_ip:DeleteLocalIP
+local_ip_list = openstackclient.network.v2.local_ip:ListLocalIP
+local_ip_set = openstackclient.network.v2.local_ip:SetLocalIP
+local_ip_show = openstackclient.network.v2.local_ip:ShowLocalIP
+network_agent_add_network = openstackclient.network.v2.network_agent:AddNetworkToAgent
+network_agent_add_router = openstackclient.network.v2.network_agent:AddRouterToAgent
+network_agent_delete = openstackclient.network.v2.network_agent:DeleteNetworkAgent
+network_agent_list = openstackclient.network.v2.network_agent:ListNetworkAgent
+network_agent_remove_network = openstackclient.network.v2.network_agent:RemoveNetworkFromAgent
+network_agent_remove_router = openstackclient.network.v2.network_agent:RemoveRouterFromAgent
+network_agent_set = openstackclient.network.v2.network_agent:SetNetworkAgent
+network_agent_show = openstackclient.network.v2.network_agent:ShowNetworkAgent
+network_auto_allocated_topology_create = openstackclient.network.v2.network_auto_allocated_topology:CreateAutoAllocatedTopology
+network_auto_allocated_topology_delete = openstackclient.network.v2.network_auto_allocated_topology:DeleteAutoAllocatedTopology
+network_create = openstackclient.network.v2.network:CreateNetwork
+network_delete = openstackclient.network.v2.network:DeleteNetwork
+network_flavor_add_profile = openstackclient.network.v2.network_flavor:AddNetworkFlavorToProfile
+network_flavor_create = openstackclient.network.v2.network_flavor:CreateNetworkFlavor
+network_flavor_delete = openstackclient.network.v2.network_flavor:DeleteNetworkFlavor
+network_flavor_list = openstackclient.network.v2.network_flavor:ListNetworkFlavor
+network_flavor_profile_create = openstackclient.network.v2.network_flavor_profile:CreateNetworkFlavorProfile
+network_flavor_profile_delete = openstackclient.network.v2.network_flavor_profile:DeleteNetworkFlavorProfile
+network_flavor_profile_list = openstackclient.network.v2.network_flavor_profile:ListNetworkFlavorProfile
+network_flavor_profile_set = openstackclient.network.v2.network_flavor_profile:SetNetworkFlavorProfile
+network_flavor_profile_show = openstackclient.network.v2.network_flavor_profile:ShowNetworkFlavorProfile
+network_flavor_remove_profile = openstackclient.network.v2.network_flavor:RemoveNetworkFlavorFromProfile
+network_flavor_set = openstackclient.network.v2.network_flavor:SetNetworkFlavor
+network_flavor_show = openstackclient.network.v2.network_flavor:ShowNetworkFlavor
+network_l3_conntrack_helper_create = openstackclient.network.v2.l3_conntrack_helper:CreateConntrackHelper
+network_l3_conntrack_helper_delete = openstackclient.network.v2.l3_conntrack_helper:DeleteConntrackHelper
+network_l3_conntrack_helper_list = openstackclient.network.v2.l3_conntrack_helper:ListConntrackHelper
+network_l3_conntrack_helper_set = openstackclient.network.v2.l3_conntrack_helper:SetConntrackHelper
+network_l3_conntrack_helper_show = openstackclient.network.v2.l3_conntrack_helper:ShowConntrackHelper
+network_list = openstackclient.network.v2.network:ListNetwork
+network_meter_create = openstackclient.network.v2.network_meter:CreateMeter
+network_meter_delete = openstackclient.network.v2.network_meter:DeleteMeter
+network_meter_list = openstackclient.network.v2.network_meter:ListMeter
+network_meter_rule_create = openstackclient.network.v2.network_meter_rule:CreateMeterRule
+network_meter_rule_delete = openstackclient.network.v2.network_meter_rule:DeleteMeterRule
+network_meter_rule_list = openstackclient.network.v2.network_meter_rule:ListMeterRule
+network_meter_rule_show = openstackclient.network.v2.network_meter_rule:ShowMeterRule
+network_meter_show = openstackclient.network.v2.network_meter:ShowMeter
+network_qos_policy_create = openstackclient.network.v2.network_qos_policy:CreateNetworkQosPolicy
+network_qos_policy_delete = openstackclient.network.v2.network_qos_policy:DeleteNetworkQosPolicy
+network_qos_policy_list = openstackclient.network.v2.network_qos_policy:ListNetworkQosPolicy
+network_qos_policy_set = openstackclient.network.v2.network_qos_policy:SetNetworkQosPolicy
+network_qos_policy_show = openstackclient.network.v2.network_qos_policy:ShowNetworkQosPolicy
+network_qos_rule_create = openstackclient.network.v2.network_qos_rule:CreateNetworkQosRule
+network_qos_rule_delete = openstackclient.network.v2.network_qos_rule:DeleteNetworkQosRule
+network_qos_rule_list = openstackclient.network.v2.network_qos_rule:ListNetworkQosRule
+network_qos_rule_set = openstackclient.network.v2.network_qos_rule:SetNetworkQosRule
+network_qos_rule_show = openstackclient.network.v2.network_qos_rule:ShowNetworkQosRule
+network_qos_rule_type_list = openstackclient.network.v2.network_qos_rule_type:ListNetworkQosRuleType
+network_qos_rule_type_show = openstackclient.network.v2.network_qos_rule_type:ShowNetworkQosRuleType
+network_rbac_create = openstackclient.network.v2.network_rbac:CreateNetworkRBAC
+network_rbac_delete = openstackclient.network.v2.network_rbac:DeleteNetworkRBAC
+network_rbac_list = openstackclient.network.v2.network_rbac:ListNetworkRBAC
+network_rbac_set = openstackclient.network.v2.network_rbac:SetNetworkRBAC
+network_rbac_show = openstackclient.network.v2.network_rbac:ShowNetworkRBAC
+network_segment_create = openstackclient.network.v2.network_segment:CreateNetworkSegment
+network_segment_delete = openstackclient.network.v2.network_segment:DeleteNetworkSegment
+network_segment_list = openstackclient.network.v2.network_segment:ListNetworkSegment
+network_segment_range_create = openstackclient.network.v2.network_segment_range:CreateNetworkSegmentRange
+network_segment_range_delete = openstackclient.network.v2.network_segment_range:DeleteNetworkSegmentRange
+network_segment_range_list = openstackclient.network.v2.network_segment_range:ListNetworkSegmentRange
+network_segment_range_set = openstackclient.network.v2.network_segment_range:SetNetworkSegmentRange
+network_segment_range_show = openstackclient.network.v2.network_segment_range:ShowNetworkSegmentRange
+network_segment_set = openstackclient.network.v2.network_segment:SetNetworkSegment
+network_segment_show = openstackclient.network.v2.network_segment:ShowNetworkSegment
+network_service_provider_list = openstackclient.network.v2.network_service_provider:ListNetworkServiceProvider
+network_set = openstackclient.network.v2.network:SetNetwork
+network_show = openstackclient.network.v2.network:ShowNetwork
+network_subport_list = openstackclient.network.v2.network_trunk:ListNetworkSubport
+network_trunk_create = openstackclient.network.v2.network_trunk:CreateNetworkTrunk
+network_trunk_delete = openstackclient.network.v2.network_trunk:DeleteNetworkTrunk
+network_trunk_list = openstackclient.network.v2.network_trunk:ListNetworkTrunk
+network_trunk_set = openstackclient.network.v2.network_trunk:SetNetworkTrunk
+network_trunk_show = openstackclient.network.v2.network_trunk:ShowNetworkTrunk
+network_trunk_unset = openstackclient.network.v2.network_trunk:UnsetNetworkTrunk
+network_unset = openstackclient.network.v2.network:UnsetNetwork
+port_create = openstackclient.network.v2.port:CreatePort
+port_delete = openstackclient.network.v2.port:DeletePort
+port_list = openstackclient.network.v2.port:ListPort
+port_set = openstackclient.network.v2.port:SetPort
+port_show = openstackclient.network.v2.port:ShowPort
+port_unset = openstackclient.network.v2.port:UnsetPort
+router_add_gateway = openstackclient.network.v2.router:AddGatewayToRouter
+router_add_port = openstackclient.network.v2.router:AddPortToRouter
+router_add_route = openstackclient.network.v2.router:AddExtraRoutesToRouter
+router_add_subnet = openstackclient.network.v2.router:AddSubnetToRouter
+router_create = openstackclient.network.v2.router:CreateRouter
+router_delete = openstackclient.network.v2.router:DeleteRouter
+router_list = openstackclient.network.v2.router:ListRouter
+router_ndp_proxy_create = openstackclient.network.v2.ndp_proxy:CreateNDPProxy
+router_ndp_proxy_delete = openstackclient.network.v2.ndp_proxy:DeleteNDPProxy
+router_ndp_proxy_list = openstackclient.network.v2.ndp_proxy:ListNDPProxy
+router_ndp_proxy_set = openstackclient.network.v2.ndp_proxy:SetNDPProxy
+router_ndp_proxy_show = openstackclient.network.v2.ndp_proxy:ShowNDPProxy
+router_remove_gateway = openstackclient.network.v2.router:RemoveGatewayFromRouter
+router_remove_port = openstackclient.network.v2.router:RemovePortFromRouter
+router_remove_route = openstackclient.network.v2.router:RemoveExtraRoutesFromRouter
+router_remove_subnet = openstackclient.network.v2.router:RemoveSubnetFromRouter
+router_set = openstackclient.network.v2.router:SetRouter
+router_show = openstackclient.network.v2.router:ShowRouter
+router_unset = openstackclient.network.v2.router:UnsetRouter
+security_group_create = openstackclient.network.v2.security_group:CreateSecurityGroup
+security_group_delete = openstackclient.network.v2.security_group:DeleteSecurityGroup
+security_group_list = openstackclient.network.v2.security_group:ListSecurityGroup
+security_group_rule_create = openstackclient.network.v2.security_group_rule:CreateSecurityGroupRule
+security_group_rule_delete = openstackclient.network.v2.security_group_rule:DeleteSecurityGroupRule
+security_group_rule_list = openstackclient.network.v2.security_group_rule:ListSecurityGroupRule
+security_group_rule_show = openstackclient.network.v2.security_group_rule:ShowSecurityGroupRule
+security_group_set = openstackclient.network.v2.security_group:SetSecurityGroup
+security_group_show = openstackclient.network.v2.security_group:ShowSecurityGroup
+security_group_unset = openstackclient.network.v2.security_group:UnsetSecurityGroup
+subnet_create = openstackclient.network.v2.subnet:CreateSubnet
+subnet_delete = openstackclient.network.v2.subnet:DeleteSubnet
+subnet_list = openstackclient.network.v2.subnet:ListSubnet
+subnet_pool_create = openstackclient.network.v2.subnet_pool:CreateSubnetPool
+subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool
+subnet_pool_list = openstackclient.network.v2.subnet_pool:ListSubnetPool
+subnet_pool_set = openstackclient.network.v2.subnet_pool:SetSubnetPool
+subnet_pool_show = openstackclient.network.v2.subnet_pool:ShowSubnetPool
+subnet_pool_unset = openstackclient.network.v2.subnet_pool:UnsetSubnetPool
+subnet_set = openstackclient.network.v2.subnet:SetSubnet
+subnet_show = openstackclient.network.v2.subnet:ShowSubnet
+subnet_unset = openstackclient.network.v2.subnet:UnsetSubnet
+
+[openstack.object_store.v1]
+container_create = openstackclient.object.v1.container:CreateContainer
+container_delete = openstackclient.object.v1.container:DeleteContainer
+container_list = openstackclient.object.v1.container:ListContainer
+container_save = openstackclient.object.v1.container:SaveContainer
+container_set = openstackclient.object.v1.container:SetContainer
+container_show = openstackclient.object.v1.container:ShowContainer
+container_unset = openstackclient.object.v1.container:UnsetContainer
+object_create = openstackclient.object.v1.object:CreateObject
+object_delete = openstackclient.object.v1.object:DeleteObject
+object_list = openstackclient.object.v1.object:ListObject
+object_save = openstackclient.object.v1.object:SaveObject
+object_set = openstackclient.object.v1.object:SetObject
+object_show = openstackclient.object.v1.object:ShowObject
+object_store_account_set = openstackclient.object.v1.account:SetAccount
+object_store_account_show = openstackclient.object.v1.account:ShowAccount
+object_store_account_unset = openstackclient.object.v1.account:UnsetAccount
+object_unset = openstackclient.object.v1.object:UnsetObject
+
+[openstack.volume.v2]
+consistency_group_add_volume = openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup
+consistency_group_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
+consistency_group_delete = openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup
+consistency_group_list = openstackclient.volume.v2.consistency_group:ListConsistencyGroup
+consistency_group_remove_volume = openstackclient.volume.v2.consistency_group:RemoveVolumeFromConsistencyGroup
+consistency_group_set = openstackclient.volume.v2.consistency_group:SetConsistencyGroup
+consistency_group_show = openstackclient.volume.v2.consistency_group:ShowConsistencyGroup
+consistency_group_snapshot_create = openstackclient.volume.v2.consistency_group_snapshot:CreateConsistencyGroupSnapshot
+consistency_group_snapshot_delete = openstackclient.volume.v2.consistency_group_snapshot:DeleteConsistencyGroupSnapshot
+consistency_group_snapshot_list = openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot
+consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot
+volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability
+volume_backend_pool_list = openstackclient.volume.v2.volume_backend:ListPool
+volume_backup_create = openstackclient.volume.v2.volume_backup:CreateVolumeBackup
+volume_backup_delete = openstackclient.volume.v2.volume_backup:DeleteVolumeBackup
+volume_backup_list = openstackclient.volume.v2.volume_backup:ListVolumeBackup
+volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
+volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
+volume_backup_restore = openstackclient.volume.v2.volume_backup:RestoreVolumeBackup
+volume_backup_set = openstackclient.volume.v2.volume_backup:SetVolumeBackup
+volume_backup_show = openstackclient.volume.v2.volume_backup:ShowVolumeBackup
+volume_create = openstackclient.volume.v2.volume:CreateVolume
+volume_delete = openstackclient.volume.v2.volume:DeleteVolume
+volume_host_failover = openstackclient.volume.v2.volume_host:FailoverVolumeHost
+volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost
+volume_list = openstackclient.volume.v2.volume:ListVolume
+volume_migrate = openstackclient.volume.v2.volume:MigrateVolume
+volume_qos_associate = openstackclient.volume.v2.qos_specs:AssociateQos
+volume_qos_create = openstackclient.volume.v2.qos_specs:CreateQos
+volume_qos_delete = openstackclient.volume.v2.qos_specs:DeleteQos
+volume_qos_disassociate = openstackclient.volume.v2.qos_specs:DisassociateQos
+volume_qos_list = openstackclient.volume.v2.qos_specs:ListQos
+volume_qos_set = openstackclient.volume.v2.qos_specs:SetQos
+volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
+volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
+volume_service_list = openstackclient.volume.v2.service:ListService
+volume_service_set = openstackclient.volume.v2.service:SetService
+volume_set = openstackclient.volume.v2.volume:SetVolume
+volume_show = openstackclient.volume.v2.volume:ShowVolume
+volume_snapshot_create = openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot
+volume_snapshot_delete = openstackclient.volume.v2.volume_snapshot:DeleteVolumeSnapshot
+volume_snapshot_list = openstackclient.volume.v2.volume_snapshot:ListVolumeSnapshot
+volume_snapshot_set = openstackclient.volume.v2.volume_snapshot:SetVolumeSnapshot
+volume_snapshot_show = openstackclient.volume.v2.volume_snapshot:ShowVolumeSnapshot
+volume_snapshot_unset = openstackclient.volume.v2.volume_snapshot:UnsetVolumeSnapshot
+volume_transfer_request_accept = openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest
+volume_transfer_request_create = openstackclient.volume.v2.volume_transfer_request:CreateTransferRequest
+volume_transfer_request_delete = openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest
+volume_transfer_request_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest
+volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest
+volume_type_create = openstackclient.volume.v2.volume_type:CreateVolumeType
+volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType
+volume_type_list = openstackclient.volume.v2.volume_type:ListVolumeType
+volume_type_set = openstackclient.volume.v2.volume_type:SetVolumeType
+volume_type_show = openstackclient.volume.v2.volume_type:ShowVolumeType
+volume_type_unset = openstackclient.volume.v2.volume_type:UnsetVolumeType
+volume_unset = openstackclient.volume.v2.volume:UnsetVolume
+
+[openstack.volume.v3]
+block_storage_cleanup = openstackclient.volume.v3.block_storage_cleanup:BlockStorageCleanup
+block_storage_cluster_list = openstackclient.volume.v3.block_storage_cluster:ListBlockStorageCluster
+block_storage_cluster_set = openstackclient.volume.v3.block_storage_cluster:SetBlockStorageCluster
+block_storage_cluster_show = openstackclient.volume.v3.block_storage_cluster:ShowBlockStorageCluster
+block_storage_log_level_list = openstackclient.volume.v3.block_storage_log_level:BlockStorageLogLevelList
+block_storage_log_level_set = openstackclient.volume.v3.block_storage_log_level:BlockStorageLogLevelSet
+block_storage_resource_filter_list = openstackclient.volume.v3.block_storage_resource_filter:ListBlockStorageResourceFilter
+block_storage_resource_filter_show = openstackclient.volume.v3.block_storage_resource_filter:ShowBlockStorageResourceFilter
+block_storage_snapshot_manageable_list = openstackclient.volume.v3.block_storage_manage:BlockStorageManageSnapshots
+block_storage_volume_manageable_list = openstackclient.volume.v3.block_storage_manage:BlockStorageManageVolumes
+consistency_group_add_volume = openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup
+consistency_group_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
+consistency_group_delete = openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup
+consistency_group_list = openstackclient.volume.v2.consistency_group:ListConsistencyGroup
+consistency_group_remove_volume = openstackclient.volume.v2.consistency_group:RemoveVolumeFromConsistencyGroup
+consistency_group_set = openstackclient.volume.v2.consistency_group:SetConsistencyGroup
+consistency_group_show = openstackclient.volume.v2.consistency_group:ShowConsistencyGroup
+consistency_group_snapshot_create = openstackclient.volume.v2.consistency_group_snapshot:CreateConsistencyGroupSnapshot
+consistency_group_snapshot_delete = openstackclient.volume.v2.consistency_group_snapshot:DeleteConsistencyGroupSnapshot
+consistency_group_snapshot_list = openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot
+consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot
+volume_attachment_complete = openstackclient.volume.v3.volume_attachment:CompleteVolumeAttachment
+volume_attachment_create = openstackclient.volume.v3.volume_attachment:CreateVolumeAttachment
+volume_attachment_delete = openstackclient.volume.v3.volume_attachment:DeleteVolumeAttachment
+volume_attachment_list = openstackclient.volume.v3.volume_attachment:ListVolumeAttachment
+volume_attachment_set = openstackclient.volume.v3.volume_attachment:SetVolumeAttachment
+volume_attachment_show = openstackclient.volume.v3.volume_attachment:ShowVolumeAttachment
+volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability
+volume_backend_pool_list = openstackclient.volume.v2.volume_backend:ListPool
+volume_backup_create = openstackclient.volume.v3.volume_backup:CreateVolumeBackup
+volume_backup_delete = openstackclient.volume.v3.volume_backup:DeleteVolumeBackup
+volume_backup_list = openstackclient.volume.v3.volume_backup:ListVolumeBackup
+volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
+volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
+volume_backup_restore = openstackclient.volume.v3.volume_backup:RestoreVolumeBackup
+volume_backup_set = openstackclient.volume.v3.volume_backup:SetVolumeBackup
+volume_backup_show = openstackclient.volume.v3.volume_backup:ShowVolumeBackup
+volume_backup_unset = openstackclient.volume.v3.volume_backup:UnsetVolumeBackup
+volume_create = openstackclient.volume.v3.volume:CreateVolume
+volume_delete = openstackclient.volume.v3.volume:DeleteVolume
+volume_group_create = openstackclient.volume.v3.volume_group:CreateVolumeGroup
+volume_group_delete = openstackclient.volume.v3.volume_group:DeleteVolumeGroup
+volume_group_failover = openstackclient.volume.v3.volume_group:FailoverVolumeGroup
+volume_group_list = openstackclient.volume.v3.volume_group:ListVolumeGroup
+volume_group_set = openstackclient.volume.v3.volume_group:SetVolumeGroup
+volume_group_show = openstackclient.volume.v3.volume_group:ShowVolumeGroup
+volume_group_snapshot_create = openstackclient.volume.v3.volume_group_snapshot:CreateVolumeGroupSnapshot
+volume_group_snapshot_delete = openstackclient.volume.v3.volume_group_snapshot:DeleteVolumeGroupSnapshot
+volume_group_snapshot_list = openstackclient.volume.v3.volume_group_snapshot:ListVolumeGroupSnapshot
+volume_group_snapshot_show = openstackclient.volume.v3.volume_group_snapshot:ShowVolumeGroupSnapshot
+volume_group_type_create = openstackclient.volume.v3.volume_group_type:CreateVolumeGroupType
+volume_group_type_delete = openstackclient.volume.v3.volume_group_type:DeleteVolumeGroupType
+volume_group_type_list = openstackclient.volume.v3.volume_group_type:ListVolumeGroupType
+volume_group_type_set = openstackclient.volume.v3.volume_group_type:SetVolumeGroupType
+volume_group_type_show = openstackclient.volume.v3.volume_group_type:ShowVolumeGroupType
+volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost
+volume_list = openstackclient.volume.v3.volume:ListVolume
+volume_message_delete = openstackclient.volume.v3.volume_message:DeleteMessage
+volume_message_list = openstackclient.volume.v3.volume_message:ListMessages
+volume_message_show = openstackclient.volume.v3.volume_message:ShowMessage
+volume_migrate = openstackclient.volume.v3.volume:MigrateVolume
+volume_qos_associate = openstackclient.volume.v2.qos_specs:AssociateQos
+volume_qos_create = openstackclient.volume.v2.qos_specs:CreateQos
+volume_qos_delete = openstackclient.volume.v2.qos_specs:DeleteQos
+volume_qos_disassociate = openstackclient.volume.v2.qos_specs:DisassociateQos
+volume_qos_list = openstackclient.volume.v2.qos_specs:ListQos
+volume_qos_set = openstackclient.volume.v2.qos_specs:SetQos
+volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
+volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
+volume_revert = openstackclient.volume.v3.volume:VolumeRevertToSnapshot
+volume_service_list = openstackclient.volume.v3.service:ListService
+volume_service_set = openstackclient.volume.v3.service:SetService
+volume_set = openstackclient.volume.v3.volume:SetVolume
+volume_show = openstackclient.volume.v3.volume:ShowVolume
+volume_snapshot_create = openstackclient.volume.v3.volume_snapshot:CreateVolumeSnapshot
+volume_snapshot_delete = openstackclient.volume.v3.volume_snapshot:DeleteVolumeSnapshot
+volume_snapshot_list = openstackclient.volume.v3.volume_snapshot:ListVolumeSnapshot
+volume_snapshot_set = openstackclient.volume.v3.volume_snapshot:SetVolumeSnapshot
+volume_snapshot_show = openstackclient.volume.v3.volume_snapshot:ShowVolumeSnapshot
+volume_snapshot_unset = openstackclient.volume.v3.volume_snapshot:UnsetVolumeSnapshot
+volume_summary = openstackclient.volume.v3.volume:VolumeSummary
+volume_transfer_request_accept = openstackclient.volume.v3.volume_transfer_request:AcceptTransferRequest
+volume_transfer_request_create = openstackclient.volume.v3.volume_transfer_request:CreateTransferRequest
+volume_transfer_request_delete = openstackclient.volume.v3.volume_transfer_request:DeleteTransferRequest
+volume_transfer_request_list = openstackclient.volume.v3.volume_transfer_request:ListTransferRequest
+volume_transfer_request_show = openstackclient.volume.v3.volume_transfer_request:ShowTransferRequest
+volume_type_create = openstackclient.volume.v3.volume_type:CreateVolumeType
+volume_type_delete = openstackclient.volume.v3.volume_type:DeleteVolumeType
+volume_type_list = openstackclient.volume.v3.volume_type:ListVolumeType
+volume_type_set = openstackclient.volume.v3.volume_type:SetVolumeType
+volume_type_show = openstackclient.volume.v3.volume_type:ShowVolumeType
+volume_type_unset = openstackclient.volume.v3.volume_type:UnsetVolumeType
+volume_unset = openstackclient.volume.v3.volume:UnsetVolume
diff -pruN 7.4.0-3/python_openstackclient.egg-info/not-zip-safe 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/not-zip-safe
--- 7.4.0-3/python_openstackclient.egg-info/not-zip-safe	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/not-zip-safe	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1 @@
+
diff -pruN 7.4.0-3/python_openstackclient.egg-info/pbr.json 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/pbr.json
--- 7.4.0-3/python_openstackclient.egg-info/pbr.json	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/pbr.json	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1 @@
+{"git_version": "9d3a956a", "is_release": false}
\ No newline at end of file
diff -pruN 7.4.0-3/python_openstackclient.egg-info/requires.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/requires.txt
--- 7.4.0-3/python_openstackclient.egg-info/requires.txt	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/requires.txt	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1,11 @@
+pbr!=2.1.0,>=2.0.0
+cryptography>=2.7
+cliff>=4.8.0
+iso8601>=0.1.11
+openstacksdk>=4.5.0
+osc-lib>=2.3.0
+oslo.i18n>=3.15.3
+python-keystoneclient>=3.22.0
+python-cinderclient>=3.3.0
+requests>=2.27.0
+stevedore>=2.0.1
diff -pruN 7.4.0-3/python_openstackclient.egg-info/top_level.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/top_level.txt
--- 7.4.0-3/python_openstackclient.egg-info/top_level.txt	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/python_openstackclient.egg-info/top_level.txt	2025-07-07 22:41:57.000000000 +0000
@@ -0,0 +1 @@
+openstackclient
diff -pruN 7.4.0-3/releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml
--- 7.4.0-3/releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    Add filters to search for enabled and disabled users and projects.
diff -pruN 7.4.0-3/releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml
--- 7.4.0-3/releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,3 @@
+---
+features:
+  - Add ``--property`` option to ``volume list`` command to filter volumes.
diff -pruN 7.4.0-3/releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml
--- 7.4.0-3/releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Add support for the new ``spice-direct`` console type, as well as the
+    exposing the ability for admins to lookup console connection information
+    via the new ``console connection show`` command.
diff -pruN 7.4.0-3/releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml
--- 7.4.0-3/releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,6 @@
+---
+upgrade:
+  - |
+    The ``openstack server set`` command has been extended with a new
+    parameter ``--auto-approve`` and the existing ``--state`` parameter
+    has been modified to require confirmation before resetting the state.
diff -pruN 7.4.0-3/releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml
--- 7.4.0-3/releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,4 @@
+---
+upgrade:
+  - |
+    Support for Python 3.9 has been dropped.
diff -pruN 7.4.0-3/releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml
--- 7.4.0-3/releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    The ``--network``, ``--port``, and ``--router`` options of the ``floating
+    ip list`` command can now be specified multiple times.
diff -pruN 7.4.0-3/releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml
--- 7.4.0-3/releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,10 @@
+---
+upgrade:
+  - |
+    The following commands have been migrated to SDK:
+
+    - ``domain create``
+    - ``domain delete``
+    - ``domain list``
+    - ``domain set``
+    - ``domain show``
diff -pruN 7.4.0-3/releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml
--- 7.4.0-3/releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,10 @@
+---
+upgrade:
+  - |
+    The following commands have been migrated to SDK:
+
+    - ``endpoint create``
+    - ``endpoint delete``
+    - ``endpoint list``
+    - ``endpoint show``
+    - ``endpoint set``
diff -pruN 7.4.0-3/releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml
--- 7.4.0-3/releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,4 @@
+---
+upgrade:
+  - |
+    Migrate ``group`` commands from keystoneclient to SDK.
diff -pruN 7.4.0-3/releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml
--- 7.4.0-3/releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Added four new network agent types to the list method filter:
+    ``ovn-controller``, ``ovn-controller-gateway``, ``ovn-metadata`` and
+    ``ovn-agent``.
diff -pruN 7.4.0-3/releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml
--- 7.4.0-3/releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,35 @@
+---
+upgrade:
+  - |
+    Support for the Block Storage (Cinder) v1 API has been officially removed
+    as it had been broken for some time. If you haven't noticed then you likely
+    don't need to do anything. However, in the unlikely event that your cloud
+    is using the Block Storage v1 API - or incorrectly advertises the Block
+    Storage v1 API - consider overriding the API version to use v2 as this
+    behaves very similarly. It may also be necessary to set an endpoint
+    override for the Block Storage API if your clouds service catalog is not
+    configured correctly. For example:
+
+    .. code-block:: yaml
+
+        example:
+          regions:
+            - name: regionOne
+              values:
+                block_storage_endpoint_override: 'https://blockstorage.api.cloud.example/'
+          volume_api_version: 2
+
+    If using a public cloud provider, there may also be a profile already
+    published that sets these. These are listed in the `Vendor Support`__
+    doc. For example:
+
+    .. code-block:: yaml
+
+        example:
+          profile: rackspace
+
+    Alternatively, consider use versions of OSC < 3.19 and python-cinderclient
+    < 5.0 (both Stein), since these were the last versions to fully support
+    Cinder v1.
+
+    .. __: https://docs.openstack.org/openstacksdk/latest/user/config/vendor-support.html
diff -pruN 7.4.0-3/releasenotes/notes/reno.cache 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/reno.cache
--- 7.4.0-3/releasenotes/notes/reno.cache	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/reno.cache	2025-07-07 22:42:17.000000000 +0000
@@ -0,0 +1,8904 @@
+---
+dates:
+- date: 1522355908
+  version: 3.14.1
+- date: 1393689343
+  version: 0.3.1
+- date: 1335902362
+  version: '0.1'
+- date: 1650904681
+  version: victoria-em
+- date: 1443726814
+  version: 1.7.1
+- date: 1728399801
+  version: 7.1.3
+- date: 1612203863
+  version: 4.0.2
+- date: 1733851868
+  version: xena-eol
+- date: 1733851962
+  version: wallaby-eol
+- date: 1481561655
+  version: 3.2.1
+- date: 1528082833
+  version: 3.14.2
+- date: 1744275570
+  version: 8.0.0
+- date: 1694793781
+  version: 6.3.0
+- date: 1375811444
+  version: 0.2.1
+- date: 1585134490
+  version: 5.1.0
+- date: 1542660258
+  version: 3.16.2
+- date: 1630523411
+  version: 5.6.0
+- date: 1738245371
+  version: 7.1.4
+- date: 1418072922
+  version: 1.0.1
+- date: 1583446831
+  version: rocky-em
+- date: 1430424949
+  version: 1.2.0
+- date: 1466768424
+  version: kilo-eol
+- date: 1748245435
+  version: 8.1.0
+- date: 1726753916
+  version: 7.1.2
+- date: 1594748883
+  version: 5.3.1
+- date: 1431468148
+  version: 1.0.4
+- date: 1439306488
+  version: 1.6.0
+- date: 1616231775
+  version: 5.5.0
+- date: 1461175146
+  version: 2.4.0
+- date: 1709801110
+  version: wallaby-eom
+- date: 1410236579
+  version: 0.4.1
+- date: 1601671763
+  version: 5.4.0
+- date: 1482349265
+  version: 3.6.0
+- date: 1501033161
+  version: 3.12.0
+- date: 1573117900
+  version: 3.16.3
+- date: 1536175683
+  version: 3.16.1
+- date: 1432763991
+  version: 1.3.0
+- date: 1722258550
+  version: 6.6.1
+- date: 1485484922
+  version: 3.8.0
+- date: 1686820710
+  version: rocky-eol
+- date: 1471899609
+  version: 3.0.1
+- date: 1555113062
+  version: ocata-em
+- date: 1678380128
+  version: 6.2.0
+- date: 1499248442
+  version: mitaka-eol
+- date: 1442942600
+  version: 1.7.0
+- date: 1471868482
+  version: 3.0.0
+- date: 1746027914
+  version: 2023.2-eol
+- date: 1703161989
+  version: train-eol
+- date: 1457045448
+  version: 2.2.0
+- date: 1465399459
+  version: 2.6.0
+- date: 1403295605
+  version: 0.4.0
+- date: 1481733527
+  version: 3.5.0
+- date: 1572447255
+  version: queens-em
+- date: 1740169736
+  version: 7.3.1
+- date: 1516887952
+  version: 3.14.0
+- date: 1532595456
+  version: 3.16.0
+- date: 1630522575
+  version: 5.5.1
+- date: 1592583397
+  version: 5.2.1
+- date: 1458682648
+  version: 1.0.5
+- date: 1434478471
+  version: 1.5.0
+- date: 1733816346
+  version: victoria-eol
+- date: 1714387709
+  version: zed-eom
+- date: 1488896402
+  version: 3.9.0
+- date: 1646743761
+  version: 5.8.0
+- date: 1479673942
+  version: 3.4.1
+- date: 1594235213
+  version: 5.3.0
+- date: 1710770659
+  version: 6.6.0
+- date: 1484579567
+  version: 3.7.0
+- date: 1722946454
+  version: 7.0.0
+- date: 1582570975
+  version: 5.0.0
+- date: 1429637120
+  version: 1.1.0
+- date: 1751448902
+  version: 7.5.0
+- date: 1621353157
+  version: train-em
+- date: 1630328241
+  version: 5.2.2
+- date: 1739971170
+  version: 7.3.0
+- date: 1726070818
+  version: 7.1.0
+- date: 1605204394
+  version: stein-em
+- date: 1487739851
+  version: 2.3.1
+- date: 1667387813
+  version: wallaby-em
+- date: 1707403182
+  version: 6.0.1
+- date: 1542660697
+  version: 3.14.3
+- date: 1513200810
+  version: 3.13.0
+- date: 1455063878
+  version: 2.1.0
+- date: 1417735300
+  version: 1.0.0
+- date: 1660815110
+  version: 6.0.0
+- date: 1574101283
+  version: 3.18.1
+- date: 1522350488
+  version: 3.12.1
+- date: 1523563135
+  version: 3.8.2
+- date: 1659117830
+  version: pike-eol
+- date: 1636709442
+  version: ussuri-em
+- date: 1592818567
+  version: 4.0.1
+- date: 1560420392
+  version: 3.19.0
+- date: 1675258095
+  version: 5.6.2
+- date: 1449173892
+  version: 2.0.0
+- date: 1426015577
+  version: 1.0.3
+- date: 1493812681
+  version: 3.10.0
+- date: 1733853829
+  version: zed-eol
+- date: 1522344431
+  version: 3.15.0
+- date: 1723048158
+  version: 6.2.1
+- date: 1447798698
+  version: 1.9.0
+- date: 1464291710
+  version: 2.5.0
+- date: 1729247821
+  version: 7.2.0
+- date: 1379692976
+  version: 0.2.2
+- date: 1555441382
+  version: 3.12.2
+- date: 1387302682
+  version: 0.3.0
+- date: 1701946744
+  version: 6.4.0
+- date: 1552018812
+  version: 3.18.0
+- date: 1450401242
+  version: 1.7.2
+- date: 1472208063
+  version: 3.1.0
+- date: 1707149660
+  version: yoga-eom
+- date: 1541747340
+  version: 3.17.0
+- date: 1726493157
+  version: 7.1.1
+- date: 1445362561
+  version: 1.8.0
+- date: 1709801168
+  version: xena-eom
+- date: 1421699488
+  version: 1.0.2
+- date: 1375397691
+  version: 0.2.rc1
+- date: 1636729876
+  version: 5.7.0
+- date: 1669979505
+  version: queens-eol
+- date: 1706786349
+  version: 6.5.0
+- date: 1555971161
+  version: pike-em
+- date: 1472636988
+  version: 3.2.0
+- date: 1730205526
+  version: 7.2.1
+- date: 1681467333
+  version: xena-em
+- date: 1508890738
+  version: newton-eol
+- date: 1676978344
+  version: 6.1.0
+- date: 1476105960
+  version: 3.3.0
+- date: 1479414990
+  version: 3.4.0
+- date: 1481719160
+  version: liberty-eol
+- date: 1375468815
+  version: 0.2.0
+- date: 1375310072
+  version: 0.2.alpha1
+- date: 1694080851
+  version: 5.8.1
+- date: 1675177927
+  version: 5.6.1
+- date: 1493924260
+  version: 3.11.0
+- date: 1709801046
+  version: victoria-eom
+- date: 1585225881
+  version: 5.2.0
+- date: 1740593143
+  version: 7.4.0
+- date: 1707234898
+  version: ussuri-eol
+- date: 1485788007
+  version: 3.8.1
+- date: 1624445744
+  version: ocata-eol
+- date: 1733853445
+  version: yoga-eol
+- date: 1731579465
+  version: 2023.1-eom
+- date: 1694094118
+  version: stein-eol
+- date: 1568281049
+  version: 4.0.0
+- date: 1459276773
+  version: 2.3.0
+- date: 1434377245
+  version: 1.4.0
+file-contents:
+  releasenotes/notes/Add-default-security-group-rule-CRUD-2916568f829ea38c.yaml:
+    features:
+    - 'Add ``default security group rule create``, ``default security group rule
+
+      delete``, ``default security group rule list`` and ``default security group
+
+      rule show`` commands to support Neutron Default Security Group Rule CRUD
+
+      operations.
+
+      [Bug `1983053 <https://bugs.launchpad.net/bugs/1983053>`_]
+
+      '
+  releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml:
+    features:
+    - 'Add ``trusted`` attribute to the ``port create`` and ``port set`` commands.
+
+      It can be set to ``true`` with ``--trusted`` and to ``false`` with
+
+      ``--not-trusted`` CLI arguments passed to the ``port create`` and ``port
+
+      set`` commands``
+
+      '
+  releasenotes/notes/L3-conntrack-helper-bd0d9da041747e84.yaml:
+    features:
+    - 'Add new commands ``network l3 conntrack helper create``,
+
+      ``network l3 conntrack helper set``, ``network l3 conntrack helper show``,
+
+      ``network l3 conntrack helper set`` and
+
+      ``network l3 conntrack helper delete`` to support Neutron L3 conntrack
+
+      helper CRUD operations.
+
+      '
+  releasenotes/notes/Router-flavor-accepts-name-or-id-e9cecafcddf81cb2.yaml:
+    fixes:
+    - 'The ``router create --flavor-id`` parameter has been deprecated
+
+      in favour of the ``--flavor`` parameter, which accepts both
+
+      flavor names and flavor IDs.
+
+      '
+  releasenotes/notes/add-auto-and-none-as-nic-parameter-ed23a6e7f99f250d.yaml:
+    features:
+    - 'Added ``auto`` and ``none`` as values for ``--nic`` to
+
+      the``server create`` command. Specifying ``none`` will not
+
+      attach a network to the server. Specifying ``auto``
+
+      will automatically attach a network. Note, v2.37 (or newer)
+
+      of the Compute API is required for these options.
+
+      [Bug `1650342 <https://bugs.launchpad.net/bugs/1650342>`_]
+
+      '
+  releasenotes/notes/add-auto-approve-cleanup-a2d225faa42dfdcb.yaml:
+    features:
+    - 'An ``--auto-approve`` option has been added to the
+
+      ``project cleanup`` command. This allows the interactive
+
+      confirmation of resource deletion to be skipped.
+
+      '
+  releasenotes/notes/add-backup-option-to-create-vol-fc36c2c745ebcff5.yaml:
+    features:
+    - 'Added ``--backup`` option to the ``volume create`` command.
+
+      '
+  releasenotes/notes/add-baremetal-agent-type-7c46365e8d457ac8.yaml:
+    features:
+    - 'Add ``baremetal`` agent type to ``--agent-type`` option for
+
+      ``network agent list`` command.
+
+      '
+  releasenotes/notes/add-block-storage-cluster-commands-fae8f686582bbbcf.yaml:
+    features:
+    - 'Add ``block storage cluster create``, ``block storage cluster delete``,
+
+      ``block storage cluster list`` and ``block storage cluster show`` commands
+
+      to create, delete, list, and show block storage service clusters,
+
+      respectively.
+
+      '
+  releasenotes/notes/add-block-storage-manage-commands-6ebf029bd7a67bb3.yaml:
+    features:
+    - 'Added ``block storage volume manageable list`` and
+
+      ``block storage snapshot manageable list`` commands that
+
+      allow operators to list the volumes and snapshots on a
+
+      particular host or cluster for management under OpenStack.
+
+      '
+  releasenotes/notes/add-cache-commands-a6f046348a3a0b1f.yaml:
+    features:
+    - 'Add commands for the image Cache API, to list, queue,
+
+      delete and clear images in the cache.
+
+      '
+  releasenotes/notes/add-cluster-to-service-list-5eab3e828de7547e.yaml:
+    features:
+    - 'Added the ``Cluster`` and ``Backend State`` columns to
+
+      ``openstack volume service list`` command. Note that the
+
+      ``Cluster`` parameter is available since microversion 3.7
+
+      and ``Backend State`` parameter is available since
+
+      microversion 3.49.
+
+      '
+  releasenotes/notes/add-community-option-to-image-list-ac0651eb2e5d632f.yaml:
+    fixes:
+    - Add ``--community`` option to ``image list`` command. [Bug `2001925 <https://storyboard.openstack.org/#!/story/2001925>`_]
+  releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml:
+    features:
+    - 'Added ``--source-group`` and ``--group-snapshot`` options to the
+
+      ``volume group create`` command to allow creating group from
+
+      a source group or a group snapshot.
+
+      '
+  releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml:
+    features:
+    - 'Add a new option `--description` to
+
+      ``floating ip port forwarding create`` and
+
+      ``floating ip port forwarding set`` commands.
+
+      '
+  releasenotes/notes/add-description-to-role-afe7b6ff668df261.yaml:
+    features:
+    - 'Now user can add the description when user create''s
+
+      the role using OSC ``openstack role create`` command.
+
+      User can add the description by adding
+
+      `--description <Description>` to OSC
+
+      ``openstack role create`` command.
+
+      '
+  releasenotes/notes/add-device_id-to-port-list-0c658db51ce43c9e.yaml:
+    features:
+    - 'Add ``--device-id`` option to the ``port list`` command.
+
+      '
+  releasenotes/notes/add-disable-reason-6e0f28459a09a60d.yaml:
+    features:
+    - 'Add ``--disable-reason`` option to the ``service set`` command
+
+      '
+  releasenotes/notes/add-dns-nameserver-overwrite-option-b866baeae12f9460.yaml:
+    features:
+    - 'Add ``--no-dns-nameserver`` option to ``subnet set`` command.
+
+      [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+      '
+  releasenotes/notes/add-fip-portforwarding-commands-6e4d8ace698ee308.yaml:
+    features:
+    - 'Add floating IP Port Forwarding commands:
+
+      ``floating ip port forwarding create``,
+
+      ``floating ip port forwarding delete``,
+
+      ``floating ip port forwarding list``,
+
+      ``floating ip port forwarding set`` and
+
+      ``floating ip port forwarding show``.
+
+      '
+  releasenotes/notes/add-flavor-id-to-router-create-76e916e129b5b80c.yaml:
+    features:
+    - 'Add the ``--flavor-id`` option to the ``router create`` command.
+
+      '
+  releasenotes/notes/add-ha-to-router-update-6a38a73cc112b2fc.yaml:
+    features:
+    - 'Add support to update high-availability property of
+
+      a router by adding ``--ha`` and ``--no-ha`` option
+
+      to ``router set`` CLI.
+
+      [Bug `1631492 <https://bugs.launchpad.net/bugs/1631492>`_]
+
+      '
+  releasenotes/notes/add-host-and-hypervisor-hostname-flag-to-create-server-cb8b39a9f9311d42.yaml:
+    features:
+    - 'Add ``--host`` and ``--hypervisor-hostname`` options to
+
+      ``server create`` command.
+
+      [Blueprint `add-host-and-hypervisor-hostname-flag-to-create-server <https://blueprints.launchpad.net/nova/+spec/add-host-and-hypervisor-hostname-flag-to-create-server>`_]'
+  releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml:
+    features:
+    - 'Added ``--import`` flag to ``openstack image create`` to allow
+
+      the user to force use of the image import codepath.
+
+      '
+  releasenotes/notes/add-image-member-get-25e913ef2b861bf3.yaml:
+    features:
+    - 'Add ``image member get`` command which accepts an
+
+      image_id and member_id and displays the detail of
+
+      the particular meber associated to the image.
+
+      '
+  releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml:
+    features:
+    - Add ``image member list`` command to list all members of an image.
+  releasenotes/notes/add-image-metadef-namespace-support-4ba37ec3a1a72185.yaml:
+    features:
+    - Adds ``openstack image metadef namespace list``. The output is equivalent to
+      glance md-namespace-list.
+  releasenotes/notes/add-image-metadef-object-property-show-4ab2c957451ea230.yaml:
+    features:
+    - 'Add ``image metadef object property show`` command which
+
+      shows a particular property inside metadef object.
+
+      '
+  releasenotes/notes/add-image-metadef-object-update-f4880e423bf4faba.yaml:
+    features:
+    - 'Add ``image metadef object update`` command which
+
+      updates the attributes of an object.
+
+      '
+  releasenotes/notes/add-image-metadef-resource-type-association-commands-4d373d7d8eca5d55.yaml:
+    features:
+    - 'Added ``image metadef resource type association list``
+
+      to list resource type associations for the image service.
+
+      This is equivalent to the
+
+      ``md-namespace-resource-type-list`` command in glance.
+
+      '
+    - 'Added ``image metadef resource type association create``
+
+      to create a resource type association for the image service.
+
+      This is equivalent to the
+
+      ``md-resource-type-associate`` command in glance.
+
+      '
+    - 'Added ``image metadef resource type association delete``
+
+      to delete a resource type association for the image service.
+
+      This is equivalent to the
+
+      ``md-resource-type-deassociate`` command in glance.
+
+      '
+  releasenotes/notes/add-image-metadef-resource-type-list-command-020adcaa2ad14e07.yaml:
+    features:
+    - 'Added ``image metadef resource type list`` command. This is equivalent to
+
+      the ``+md-namespace-resource-type-list`` command in glanceclient.
+
+      '
+  releasenotes/notes/add-image-progress-option-to-create-1ed1881d58ebad4b.yaml:
+    features:
+    - 'Add ``--progress`` option to ``image create`` command to enable a progress
+
+      bar when creating and uploading an image.
+
+      '
+  releasenotes/notes/add-image-project-filter-support-ed6204391e503adf.yaml:
+    features:
+    - 'Add ``--project`` and ``--project-domain``options to ``image list``
+
+      command to filter by owner.
+
+      '
+  releasenotes/notes/add-image-tag-filter-support-5cb039416b07caab.yaml:
+    features:
+    - 'Add ``--tag`` option to ``image list`` command to filter by tag.
+
+      '
+  releasenotes/notes/add-image-task-commands-50c3643ebfd0421f.yaml:
+    features:
+    - 'Add ``image task show`` command to show a task for the image service.
+
+      '
+    - 'Add ``image task list`` command to list tasks for the image service.
+
+      '
+  releasenotes/notes/add-implied-role-0cdafb131fbd7453.yaml:
+    features:
+    - 'Support for creating, deleting, and listing implied roles has been added.
+
+      This allows users to create an inference rule between two roles. The
+
+      first, called the prior role is the role explicitly assigned to an
+
+      individual. The second, called the implied role, is one that the user
+
+      is assgined implicitly.  Additionally, these rules can be chained, such
+
+      that an implied role from the first inference rule can be the implied role
+
+      in the second.  Thus one explicitly assigned role can lead to multiple
+
+      implied roles.
+
+      ``implied role create <role> --implied-role <implied-role>`` creates an
+
+      association between prior and implied roles.
+
+      ``implied role delete <role> --implied-role <implied-role>`` removes an
+
+      association between prior and implied roles.
+
+      ``implied role list`` Lists all implied roles that currently exist.
+
+      '
+  releasenotes/notes/add-import-info-stores-delete-c50b5222c21e1077.yaml:
+    features:
+    - 'Add ``image import info`` command, allowing users to know available import
+
+      methods, and `--store` option to ``image delete``, allowing users to delete
+
+      image from particular store.
+
+      '
+  releasenotes/notes/add-is-default-to-network-qos-policy-89b11d4df032a789.yaml:
+    features:
+    - 'Add ``--default``  and ``--no-default`` options to
+
+      ``network qos policy create`` and ``network qos policy set``
+
+      comamnds.
+
+      [Bug `1639220 <https://bugs.launchpad.net/bugs/1639220>`_]
+
+      '
+  releasenotes/notes/add-keypairs-project-filter-99cb6938f247927f.yaml:
+    features:
+    - 'It is now possible to list the keypairs for all users in a project using
+
+      the ``--project`` parameter. This is an admin-only action by default and
+
+      requires Compute API microversion 2.10 or later.
+
+      '
+  releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml:
+    features:
+    - 'It is now possible to list the keypairs for a specific user using the
+
+      ``--user`` parameter. This is an admin-only action by default and requires
+
+      Compute API microversion 2.10 or later.
+
+      '
+  releasenotes/notes/add-ksa-7f0795157d93a898.yaml:
+    other:
+    - 'Add dependency on keystoneauth1 module to perform authentication in place
+
+      of python-keystoneclient.
+
+      '
+  releasenotes/notes/add-member-status-filter-2e118b2c93151223.yaml:
+    features:
+    - Add ``--member-status`` option to ``image list`` command.
+  releasenotes/notes/add-metadef-object-create-3939ee1453585484.yaml:
+    features:
+    - 'Add ``image metadef object show`` command to create the
+
+      metadata definitions objects inside a specific namespace
+
+      '
+  releasenotes/notes/add-metadef-object-list-c8831e73c696b9d9.yaml:
+    features:
+    - 'Add ``image metadef object list`` command to list the
+
+      metadata definitions objects inside a specific namespace
+
+      '
+  releasenotes/notes/add-metadef-object-show-1b05dd33ecf42210.yaml:
+    features:
+    - 'Add ``image metadef object show`` command to show the
+
+      metadata definitions objects inside a specific namespace
+
+      '
+  releasenotes/notes/add-metadef-property-create-c9a4ec2bced892af.yaml:
+    features:
+    - 'Add ``image metadef property create`` command to create a new
+
+      metadef property inside a specific namespace.
+
+      '
+  releasenotes/notes/add-metadef-property-delete-ebb999d92a588ad4.yaml:
+    features:
+    - 'Add ``image metadef property delete`` command to delete a
+
+      metadef property inside a specific namespace.
+
+      '
+  releasenotes/notes/add-metadef-property-list-fe89ae8ff9780002.yaml:
+    features:
+    - 'Add ``image metadef property list`` command to list the
+
+      metadata definitions properties inside a specific namespace.
+
+      '
+  releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml:
+    features:
+    - 'Add ``image metadef property set`` command to update a
+
+      metadef property inside a specific namespace.
+
+      '
+  releasenotes/notes/add-metadef-property-show-8bf2ec421f74cb2d.yaml:
+    features:
+    - 'Add ``image metadef property show`` command to show details
+
+      about a metadef property inside a specific namespace.
+
+      '
+  releasenotes/notes/add-missing-hypervisor-list-opts-71da2cc36eac4edd.yaml:
+    features:
+    - 'Add ``--limit`` and ``--marker`` options to ``hypervisor list`` command, to
+
+      configure pagination of results.
+
+      '
+  releasenotes/notes/add-missing-keypair-list-opts-243a33d8276f91b8.yaml:
+    features:
+    - 'Add ``--limit`` and ``--marker`` options to ``keypair list`` command, to
+
+      configure pagination of results.
+
+      '
+  releasenotes/notes/add-missing-server-create-opts-d5e32bd743e9e132.yaml:
+    deprecations:
+    - 'The ``--block-device-mapping`` option of the ``server create`` command
+
+      has been deprecated in favour of ``--block-device``. The format of the
+
+      ``--block-device-mapping`` option is based on the limited "BDM v1"
+
+      format for block device maps introduced way back in the v1 nova API. The
+
+      ``--block-device`` option instead exposes the richer key-value based
+
+      "BDM v2" format.
+
+      '
+    features:
+    - 'Add a number of additional options to the ``server create`` command:
+
+
+      - ``--snapshot``
+
+      - ``--ephemeral``
+
+      - ``--swap``
+
+      - ``--block-device``
+
+      '
+  releasenotes/notes/add-missing-server-delete-opts-071c3e054e3ce674.yaml:
+    features:
+    - 'Add ``--force`` option to ``server delete`` command, allowing users to
+
+      force delete a server. This is admin-only by default.
+
+      '
+  releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml:
+    features:
+    - 'Add ``--limit`` and ``--offset`` options to ``server group list`` command,
+
+      to configure pagination of results.
+
+      '
+  releasenotes/notes/add-missing-server-group-list-opts-ebcf84bfcea07a4b.yaml:
+    features:
+    - 'Add ``--limit``, ``--marker``, ``--change-since`` and ``--changes-before``
+
+      options to ``server group list`` command, to configure pagination of
+
+      results and filter results by last modification, respectively.
+
+      '
+  releasenotes/notes/add-missing-server-image-create-opts-3c19a7492dc50fd7.yaml:
+    features:
+    - 'Add ``--property`` option to ``server image create`` command, allowing
+
+      users to record arbitrary key/value metadata to ``meta_data.json`` on
+
+      the metadata server.
+
+      '
+  releasenotes/notes/add-missing-server-list-opts-c41e97e86ff1e1ca.yaml:
+    features:
+    - 'Add a number of additional options to the ``server list`` command:
+
+
+      - ``--availability-zone``
+
+      - ``--key-name``
+
+      - ``--config-drive``, ``--no-config-drive``
+
+      - ``--progress``
+
+      - ``--vm-state``
+
+      - ``--task-state``
+
+      - ``--power-state``
+
+      '
+    upgrade:
+    - 'The ``openstack server list --status`` parameter will now validate the
+
+      requested status.
+
+      '
+  releasenotes/notes/add-missing-server-rebuild-opts-5c75e838d8f0487d.yaml:
+    features:
+    - 'Add a number of additional options to the ``server rebuild`` command:
+
+
+      - ``--name``
+
+      - ``--preserve-ephemeral``, ``--no-preserve-ephemeral``
+
+      - ``--user-data``, ``--no-user-data``
+
+      - ``--trusted-image-cert``, ``--no-trusted-image-certs``
+
+      '
+    upgrade:
+    - 'The ``--key-unset`` option of the ``server rebuild`` command has been
+
+      replaced by ``--no-key-name``. An alias is provided.
+
+      '
+  releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml:
+    features:
+    - 'Add ``--no-password`` option to ``server set`` command, allowing users
+
+      to clear the admin password from the metadata service. Note that this does
+
+      not actually change the server password.
+
+      '
+    upgrade:
+    - 'The ``server set --root-password`` option has been deprecated in favour of
+
+      a non-interactive ``--password`` option.
+
+      '
+  releasenotes/notes/add-missing-trust-list-opts-500fd1e4c14e1504.yaml:
+    features:
+    - 'Add missing ``--trustee``, ``--trustee-domain``, ``--trustor``,
+
+      ``--trustor-domain`` options to ``trust list`` command, to allow
+
+      filtering trusts by trustee and trustor.
+
+      '
+    - 'Add ``--authuser`` option to ``trust list`` command, to allow
+
+      displaying only trusts related to current authenticated user
+
+      '
+  releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml:
+    features:
+    - 'Add ``--no-incremental``, ``--property`` and ``--availability-zone``
+
+      options to ``volume backup create`` command, allowing users to request a
+
+      non-incremental backup, set a metadata property on the created backup, and
+
+      set an availability zone on the created backup, respectively.
+
+      '
+    - 'Add ``--property`` and ``--no-property`` options to the
+
+      ``volume backup set`` command to set a metadata property or remove all
+
+      metadata properties from an existing backup.
+
+      '
+    - 'Add new ``volume backup unset`` command to allow unsetting of properties
+
+      from an existing volume backup.
+
+      '
+    fixes:
+    - 'The ``--name`` and ``--description`` options of the ``volume backup set``
+
+      command will now verify the version requested on the client side.
+
+      Previously this would fail on the server side.
+
+      '
+  releasenotes/notes/add-more-server-list-columns-4e3b87929dd330f7.yaml:
+    feature:
+    - 'The ``server list`` command now allows users to select the following
+
+      additional columns using the ``-c COLUMN`` option:
+
+
+      - Task State
+
+      - Power State
+
+      - Image ID
+
+      - Flavor ID
+
+      - Availability Zone
+
+      - Host
+
+      - Properties
+
+
+      These correspond to columns displayed by default when using the ``--long``
+
+      option.'
+  releasenotes/notes/add-network-auto-allocated-topology-481580f48840bfc4.yaml:
+    features:
+    - 'Add support for the ``network auto allocated topology`` command for
+
+      creating and deleting auto allocated topologies.
+
+      [Blueprint :oscbp:`network-auto-allocated-topology`]
+
+      '
+  releasenotes/notes/add-network-flavor-profile-e7cc5b353c3ed9d9.yaml:
+    features:
+    - 'Add support for Network Flavor Profile commands:
+
+      ``network flavor profile create``, ``network flavor profile delete``,
+
+      ``network flavor profile list``, ``network flavor profile show`` and
+
+      ``network flavor profile set``
+
+      [Blueprint :oscbp:`neutron-client-flavors`]
+
+      '
+  releasenotes/notes/add-network-list-option-to-ports-9d101344ddeb3e64.yaml:
+    features:
+    - 'Ports can now be listed as per the networks they are
+
+      connected to by using the ``--network`` option with
+
+      the ``port list`` CLI.
+
+      [ Blueprint `network-commands-options <https://blueprints.launchpad.net/python-openstackclient/+spec/network-commands-options>`_]
+
+      '
+  releasenotes/notes/add-network-local-ip-df3a9ce7610d8b90.yaml:
+    features:
+    - Add ``local ip create``, ``local ip delete``, ``local ip list``, ``local ip
+      set``, ``local ip show``, ``local ip association create``, ``local ip association
+      delete`` and ``local ip association list`` commands to support Neutron Local
+      IP CRUD operations. [`bug 1930200 <https://bugs.launchpad.net/neutron/+bug/1930200>`_]
+  releasenotes/notes/add-network-qos-policy-b8ad1e408d73c279.yaml:
+    features:
+    - 'Add support for Network QoS policies commands:
+
+      ``network qos policy create``, ``network qos policy delete``,
+
+      ``network qos policy list``, ``network qos policy show`` and
+
+      ``network qos policy set``
+
+      [Bug `1609037 <https://bugs.launchpad.net/bugs/1609037>`_]
+
+      '
+  releasenotes/notes/add-network-qos-rule-22cc1ddd509941db.yaml:
+    features:
+    - 'Add support for Network QoS rule commands:
+
+      ``network qos rule create``, ``network qos rule delete``,
+
+      ``network qos rule list``, ``network qos rule show`` and
+
+      ``network qos rule set``
+
+      [Bug `1609472 <https://bugs.launchpad.net/bugs/1609472>`_]
+
+      '
+  releasenotes/notes/add-network-qos-rule-type-show-57a714a1d428726e.yaml:
+    features:
+    - 'Add ``network qos rule type show`` command.
+
+      '
+  releasenotes/notes/add-network-qos-rule-types-337e464c6e81f29c.yaml:
+    features:
+    - 'Add support for Network QoS rule type commands:
+
+      ``network qos rule type list``,
+
+      [Bug `1612194 <https://bugs.launchpad.net/bugs/1612194>`_]
+
+      '
+  releasenotes/notes/add-network-rbac-list-tenant-project-filter-1228f2287284e33c.yaml:
+    features:
+    - 'Add a new argument ``--target-project`` to the ``network rbac list``
+
+      command to filter for a specific target project.'
+  releasenotes/notes/add-network-service-provider-c161a4a328a8a408.yaml:
+    features:
+    - 'Add ``network service provider list`` command.
+
+      '
+  releasenotes/notes/add-no-property-f97e4b2f390cec06.yaml:
+    features:
+    - 'Add support to clear/overwrite all flavor properties using
+
+      ``--no-property`` option with ``flavor set`` command.
+
+      [Blueprint  :oscbp:`allow-overwrite-set-options`]
+
+      '
+  releasenotes/notes/add-option-to-unset-port-host-c76de9b1d2addf9a.yaml:
+    features:
+    - 'Add possibility to unbind Neutron''s port from the host by unsetting its
+
+      host_id.
+
+      '
+  releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml:
+    features:
+    - 'OSprofiler support was added. To initiate OpenStack request tracing
+
+      ``--profile <HMAC_KEY>`` option needs to be added to the CLI command. This
+
+      key needs to present one of the secret keys defined in the OpenStack
+
+      projects configuration files (if there is a wish to generate cross-project
+
+      trace, the chosen key needs to be presented in all these configuration
+
+      files). By default all OpenStack projects, that support OSprofiler,
+
+      are using ``SECRET_KEY`` HMAC key.
+
+
+      To use tracing functionality OSprofiler (and its storage backend)
+
+      needs to be installed in the environment. If so, you will be able to
+
+      trigger profiling via `openstack --profile SECRET_KEY <operation>` command.
+
+      At the end of output there will be message with <trace_id>, and to plot
+
+      human-readable HTML chart the following command should be used -
+
+      ``osprofiler trace show <trace_id> --html --out result.html``.
+
+      '
+  releasenotes/notes/add-overwrite-option-to-router-7c50c8031dab6bae.yaml:
+    features:
+    - 'Add  ``--router`` and ``--no-router`` options to ``osc router set`` command
+      to
+
+      modify routes in a router instance.
+
+      [ Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+      '
+  releasenotes/notes/add-parent-list-option-to-projects-10382a7176993366.yaml:
+    features:
+    - 'Add ``--parent`` option to ``project list`` command to filter projects
+
+      by the specified parent project.
+
+      '
+  releasenotes/notes/add-port-commands-a3580662721a6312.yaml:
+    features:
+    - 'Add ``port create``, ``port list`` and ``port set`` commands
+
+      [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
+
+      '
+  releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml:
+    features:
+    - 'Add support for the ``port delete`` command.
+
+      [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
+
+      '
+  releasenotes/notes/add-port-hardware-offload-type-011c98ab748357d7.yaml:
+    features:
+    - 'Add the port hardware offload attribute to the ``port create`` command.
+
+      Once defined, the value cannot be modified.
+
+      '
+  releasenotes/notes/add-port-hints-attribute-be1779e640a47d0d.yaml:
+    features:
+    - 'Enable management of Neutron port hints: ``port create --hint HINT``,
+
+      ``set port --hint HINT and ``unset port --hint``. Port hints allow
+
+      passing backend specific hints to Neutron mainly to tune backend
+
+      performance. The first hint controls Open vSwitch Tx steering.
+
+      '
+  releasenotes/notes/add-port-list-status-option-f51da0aed0528a5d.yaml:
+    features:
+    - 'Add ``--status`` option to ``port list`` command.
+
+      [Bug `1672680 <https://bugs.launchpad.net/python-openstackclient/+bug/1672680>`_]
+
+      '
+  releasenotes/notes/add-port-numa-affinity-policy-4706b0f9485a5d4d.yaml:
+    features:
+    - 'Add NUMA affinity policy to ``port create``, ``port set`` and
+
+      ``port unset`` commands.
+
+      '
+  releasenotes/notes/add-port-numa-affinity-policy-socket-5a986b14033e0f6e.yaml:
+    features:
+    - 'Add a new NUMA affinity policy option: "socket". That applies to any new
+
+      port (using ``port create``) or any existing port (using ``port set``).
+
+      '
+  releasenotes/notes/add-port-ranges-in-port-forwarding-command-8c6ee05cf625578a.yaml:
+    features:
+    - 'Add port ranges support to the ``floating ip port forwarding`` commands.
+
+      '
+  releasenotes/notes/add-port-security-enabled-to-port-set-82b801d21d45e715.yaml:
+    features:
+    - 'Add ``--enable-port-security`` and ``--disable-port-security``
+
+      options to ``port set`` and ``port create`` commands.
+
+      [Blueprint :oscbp:`network-commands-options`]
+
+      '
+  releasenotes/notes/add-port-show-command-de0a599017189a21.yaml:
+    features:
+    - 'Add support for the ``port show`` command.
+
+      [Bug `1519909 <https://bugs.launchpad.net/python-openstackclient/+bug/1519909>`_]
+
+      '
+  releasenotes/notes/add-port-unset-command-8bdaf1fa9c593374.yaml:
+    features:
+    - 'Add a new command ``port unset`` to clear the information
+
+      of fixed-ip and binding-profile from the port.
+
+      [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+      '
+  releasenotes/notes/add-project-cleanup-beb08c9df3c95b24.yaml:
+    features:
+    - 'Add support for project cleanup based on the OpenStackSDK with
+
+      create/update time filters. In the long run this will replace
+
+      `openstack project purge` command.
+
+      '
+  releasenotes/notes/add-qos-policy-list-options-9ba1ae731a88e7ac.yaml:
+    features:
+    - Add ``--share``, ``--no-share``, ``--project``, ``--project-domain`` options
+      to ``qos policy list`` command. [Blueprint `network-commands-options <https://blueprints.launchpad.net/python-openstackclient/+spec/network-commands-options>`_]
+  releasenotes/notes/add-quota-list-command-0d865fac61db2430.yaml:
+    features:
+    - 'Add ``quota list`` command with ``--compute``, ``--volume``
+
+      and ``--network`` options.
+
+      [Blueprint `quota-list <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-quota>`_]
+
+      '
+  releasenotes/notes/add-quota-set-for-network-11fcd7b9e08624b5.yaml:
+    features:
+    - 'Add network support for ``quota set`` command. Options added includes
+
+      ``--networks --subnets --subnetpools --ports --routers --rbac-policies``
+
+      ``--vips --members --health-monitors``.
+
+      Options ``--floating-ips --secgroup-rules --secgroups`` now support
+
+      both network and compute API.
+
+      [Bug `1489441 <https://bugs.launchpad.net/bugs/1489441>`_]
+
+      '
+  releasenotes/notes/add-reimage-param-to-rebuild-606dd331677b5954.yaml:
+    features:
+    - 'The ``server rebuild`` commands now accept two optional
+
+      ``--reimage-boot-volume`` and ``--no-reimage-boot-volume``option.
+
+      Passing these parameter will allow/disallow a user to rebuild a volume
+
+      backed server.
+
+      This is available from Compute microversion ``2.93`` and onwards.
+
+      '
+  releasenotes/notes/add-remote-managed-vnic-type-4fc540b47427c37f.yaml:
+    features:
+    - 'Support for the ``remote-managed`` VNIC type has been added and can now be
+
+      passed to the ``--vnic-type`` option when used in conjunction with the
+
+      ``port create`` and ``port set`` commands.
+
+      '
+  releasenotes/notes/add-remove-multiple-security-groups-2c0b2d599124c9c9.yaml:
+    features:
+    - 'The ``server add security group`` and ``server remove security group``
+
+      commands now accept multiple security groups.
+
+      '
+  releasenotes/notes/add-restore-server-d8c73e0e83df17dd.yaml:
+    features:
+    - 'Add ``server restore`` command
+
+      '
+  releasenotes/notes/add-server-add-network-98ede8ff6079eb23.yaml:
+    features:
+    - 'Add ``server add network`` command. This command will create a neutron
+
+      port from the specified neutron network and attach the port to the
+
+      specified instance.
+
+      '
+  releasenotes/notes/add-server-backup-e63feaebb6140f83.yaml:
+    features:
+    - Add ``server backup create`` command
+  releasenotes/notes/add-server-create-image-property-ef76af26233b472b.yaml:
+    features:
+    - 'Add  ``--image-property`` option to ``server create`` command.
+
+      This parameter will filter a image which properties that are matching.
+
+      '
+  releasenotes/notes/add-server-evacuate-8359246692cb642f.yaml:
+    features:
+    - 'Add ``server evacuate`` command. This command will recreate an instance
+
+      from scratch on a new host and is intended to be used when the original
+
+      host fails.
+
+      '
+  releasenotes/notes/add-server-group-quotas-b67fcba98619f0c9.yaml:
+    features:
+    - 'Added support of --server-groups --server-group-members options to ``quota
+      set`` command.
+
+      [Bug `1602223 <https://bugs.launchpad.net/python-openstackclient/+bug/1602223>`_]'
+  releasenotes/notes/add-server-hostname-opts-3cb4fd90b5bf47ca.yaml:
+    features:
+    - 'The ``server create``, ``server set`` and ``server rebuild`` commands now
+
+      accept an optional ``--hostname HOSTNAME`` option. This can be used to
+
+      configure the hostname stored in the metadata service and/or config drive.
+
+      Utilities such as ``cloud-init`` can then consume this information to set
+
+      the hostname within the guest OS.
+
+      '
+  releasenotes/notes/add-server-migrate-confirm-revert-commands-9d8079c9fddea36d.yaml:
+    features:
+    - 'Add ``server migrate confirm`` and ``server migrate revert`` commands.
+
+      These are aliases of the ``server resize confirm`` and ``server resize revert``
+
+      commands, respectively.
+
+      '
+  releasenotes/notes/add-server-migrate-with-host-4884a71903c5c8a9.yaml:
+    features:
+    - 'Add ``--host`` option to ``server migrate`` command
+
+      (cold migration) to specify the target host of the migration.
+
+      Requires ``--os-compute-api-version`` 2.56 or greater to target a
+
+      specific host for the (cold) migration.
+
+      [Story `2003325 <https://storyboard.openstack.org/#!/story/2003325>`_]
+
+      '
+  releasenotes/notes/add-server-migration-show-command-2e3a25e383dc5d70.yaml:
+    features:
+    - 'Add ``server migration show`` commands. This can be used to show detailed
+
+      information about an ongoing server migration.
+
+      '
+  releasenotes/notes/add-server-nic-tagging-support-f77b4247e87771d5.yaml:
+    features:
+    - 'The ``--nic`` option of the ``server create`` command now supports an
+
+      optional ``tag=<tag>`` key-value pair. This can be used to set a tag for
+
+      the interface in server metadata, which can be useful to maintain
+
+      persistent references to interfaces during various operations.
+
+      '
+  releasenotes/notes/add-server-remove-network-fb09c53d5b0c0068.yaml:
+    features:
+    - 'Add ``server remove network`` command. This command will remove all
+
+      network ports from the specified network and instance.
+
+      '
+  releasenotes/notes/add-server-resize-confirm-revert-commands-98854ca98965432a.yaml:
+    deprecations:
+    - 'Deprecate the ``--confirm`` and ``--revert`` options for the
+
+      ``server resize`` command. They have been replaced with the
+
+      ``server resize confirm`` and `server resize revert`` commands,
+
+      respectively.
+
+      '
+    features:
+    - 'Add ``server resize confirm`` and ``server resize revert`` commands.
+
+      These replace the now deprecated ``--confirm`` and ``--revert``
+
+      options to the ``server resize`` commands, respectively.
+
+      '
+  releasenotes/notes/add-server-volume-update-89740dca61596dd1.yaml:
+    features:
+    - 'Add ``server volume list`` command, to list the volumes attached to an
+
+      instance.
+
+      '
+    - 'Add ``server volume update`` command, to update the volumes attached to
+
+      an instance.
+
+      '
+  releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml:
+    features:
+    - 'Add support for ``--offload`` and ``--wait`` options for ``server shelve``.
+
+      ``--offload`` allows users to explicitly request offloading of a shelved
+
+      server in environments where automatic offloading is not configured, while
+
+      ``--wait`` allows users to wait for the shelve and/or shelve offload
+
+      operations to complete.
+
+      '
+    - 'Add support ``--wait`` option for ``server shelve``.
+
+      '
+  releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml:
+    features:
+    - 'Added support for unmanaging snapshots with the
+
+      ``openstack snapshot delete --remote`` command.
+
+      '
+  releasenotes/notes/add-stores-info-9f1488dd29013767.yaml:
+    features:
+    - 'Add ``image stores info`` command, allowing users to know available backends.
+
+      '
+  releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml:
+    features:
+    - 'Add support for the ``subnet list`` command.
+
+      [Bug `1523258 <https://bugs.launchpad.net/python-openstackclient/+bug/1523258>`_]
+
+      '
+  releasenotes/notes/add-tag-support-server-add-fixed-ip-8de2db58f2a80e85.yaml:
+    features:
+    - Add ``--tag`` option to ``server add fixed ip`` command when adding a fixed
+      IP to server. Only available starting with ``--os-compute-api-version 2.49``.
+  releasenotes/notes/add-tag-support-server-add-network-a8590cab5d7babf0.yaml:
+    features:
+    - Add ``--tag`` option to ``server add network`` command when add network to server.
+      Only available starting with ``--os-compute-api-version 2.49``.
+  releasenotes/notes/add-tag-support-server-add-port-7e30aa38202d0839.yaml:
+    features:
+    - Add ``--tag`` option to ``server add port`` command when add a port to server.
+      Only available starting with ``--os-compute-api-version 2.49``.
+  releasenotes/notes/add-tag-support-server-add-volume-278e79a22dd482f4.yaml:
+    features:
+    - Add ``--tag`` option to ``server add volume`` command when add a volume to server.
+      Only available starting with ``--os-compute-api-version 2.49``.
+  releasenotes/notes/add-trusted-certs-option-server-create-a660488407300f22.yaml:
+    features:
+    - 'Added ``--trusted-image-cert`` option for server create. It is available
+
+      only when directly booting server from image (not from volume, not from
+
+      snapshot and not via image converted to volume first).
+
+      This option is supported for Compute API version >=2.63
+
+      '
+  releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml:
+    features:
+    - 'Add filters to search for enabled and disabled users and projects.
+
+      '
+  releasenotes/notes/add-virtio-forwarder-vnic-type-bad939c6a868b9e9.yaml:
+    features:
+    - 'The ``virtio-forwarder`` VNIC type has been added as another option for
+
+      setting the ``--vnic-type`` property on the ``port set`` and
+
+      ``port create`` commands. This requests a low-latency virtio port inside
+
+      the instance, likely backed by hardware acceleration. Currently the
+
+      Agilio OVS external plugin provides support for this, with support from
+
+      other vendors following soon.
+
+      '
+  releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml:
+    features:
+    - 'Add ``qinq-vlan`` and ``no-qinq-vlan`` arguments to the ``network create``
+
+      command. It will enable/disable QinQ feature for the created network.
+
+      This new argument is mutually exclusive with the ``transparent-vlan`` - only
+
+      one of them can be set to ``True`` for the network.
+
+      '
+  releasenotes/notes/add-vol-service-get-set-log-commands-f9420e5061d994b5.yaml:
+    features:
+    - 'Added ``block storage log level list`` and ``block storage log level set``
+
+      commands that allows operators to list and set log levels for cinder
+
+      services.
+
+      '
+  releasenotes/notes/add-volume-attachment-commands-db2974c6460fa3bc.yaml:
+    features:
+    - 'Add ``volume attachment create``, ``volume attachment delete``,
+
+      ``volume attachment list``, ``volume attachment complete``,
+
+      ``volume attachment set`` and ``volume attachment show`` commands to
+
+      create, delete, list, complete, update and show volume attachments,
+
+      respectively.
+
+      '
+  releasenotes/notes/add-volume-group-commands-b121d6ec7da9779a.yaml:
+    features:
+    - 'Add ``volume group create``, ``volume group delete``,
+
+      ``volume group list``, ``volume group failover``,
+
+      ``volume group set`` and ``volume attachment show``
+
+      commands to create, delete, list, failover, update and show volume groups,
+
+      respectively.
+
+      '
+  releasenotes/notes/add-volume-group-snapshot-commands-27fa8920d55f6bdb.yaml:
+    features:
+    - 'Add ``volume group snapshot create``, ``volume group snapshot delete``,
+
+      ``volume group snapshot list`` and ``volume group snapshot show`` commands
+
+      to create, delete, list, and show volume group snapshots, respectively.
+
+      '
+  releasenotes/notes/add-volume-group-type-commands-13eabc7664a5c2bc.yaml:
+    features:
+    - 'Add ``volume group type create``, ``volume group type delete``,
+
+      ``volume group type list``, ``volume group type set/unset`` and
+
+      ``volume group type show`` commands to create, delete, list, update,
+
+      and show volume group types, respectively.
+
+      '
+  releasenotes/notes/add-volume-host-failover-8fc77b24533b7fed.yaml:
+    features:
+    - 'Add ``volume host failover`` command.
+
+      [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+      '
+  releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml:
+    features:
+    - Add ``--property`` option to ``volume list`` command to filter volumes.
+  releasenotes/notes/add-volume-manage-command-088890446d0e81c7.yaml:
+    features:
+    - 'Add support for managing volumes with
+
+      ``openstack volume create --remote-source <key=val>
+
+      --host <host>`` command.
+
+      '
+  releasenotes/notes/add-volume-message-commands-89a590a1549c333e.yaml:
+    features:
+    - 'Add ``volume message list``, ``volume message get`` and
+
+      ``volume message delete`` commands, to list, get and delete volume
+
+      failure messages, respectively.
+
+      '
+  releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml:
+    features:
+    - 'Add ``--no-property`` option in ``volume qos set``.
+
+      '
+  releasenotes/notes/add-volume-revert-command-1c8f695420acbe7e.yaml:
+    features:
+    - 'Added ``volume revert`` command that reverts
+
+      the volume to the given snapshot.
+
+      '
+  releasenotes/notes/add-volume-summary-command-b2175b48af3ccab1.yaml:
+    features:
+    - 'Added ``volume summary`` command to show the total size,
+
+      total count and metadata of volumes.
+
+      '
+  releasenotes/notes/add-volume-transfer-request-create-snapshots-opts-1361416d37021e89.yaml:
+    features:
+    - 'The ``volume transfer request create`` command now accepts the
+
+      ``--snapshots`` / ``--no-snapshots`` option to configure whether to
+
+      create a transfer request for a volume without snapshots or not.
+
+      '
+  releasenotes/notes/add-volume-type-set-public-private-opts-891fc7ab5de9bb6a.yaml:
+    features:
+    - 'The ``volume type set`` command now supports ``--public`` and ``--private``
+
+      options.
+
+      '
+  releasenotes/notes/add-volume-unmanage-support-9b7139e5e948de77.yaml:
+    features:
+    - 'Add support for unmanaging volumes with
+
+      ``openstack volume delete --remote <volume>`` command.
+
+      '
+  releasenotes/notes/add-workers-cleanup-command-720573c0f642efe9.yaml:
+    features:
+    - 'Added ``block storage cleanup`` command that allows cleanup
+
+      of resources (volumes and snapshots) by services in other nodes
+
+      in a cluster in an Active-Active deployments.
+
+      '
+  releasenotes/notes/add_attachment_id_to_volume_attachment-cea605585db29e14.yaml:
+    features:
+    - 'Added support for `microversion 2.89`_. This microversion removes the
+
+      ``id`` field while adding the ``attachment_id`` and ``bdm_uuid`` fields to
+
+      the responses of ``GET /servers/{server_id}/os-volume_attachments`` and
+
+      ``GET /servers/{server_id}/os-volume_attachments/{volume_id}`` with these
+
+      changes reflected in novaclient under the ``openstack server volume list``
+
+      command.
+
+
+      .. _microversion 2.89: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-89
+
+      '
+  releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml:
+    features:
+    - Add ``--id`` and ``--enabled`` option to ``identity provider list`` command.
+  releasenotes/notes/add_name_and_enabled_to_list_domain-6d23f02994b51c67.yaml:
+    features:
+    - Add ``--name`` and ``--domain`` option to ``domain list`` command.
+  releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml:
+    features:
+    - 'Added the below mentioned parameters to the user create and set commands.
+
+
+      * --ignore-lockout-failure-attempts
+
+      * --no-ignore-lockout-failure-attempts
+
+      * --ignore-password-expiry
+
+      * --no-ignore-password-expiry
+
+      * --ignore-change-password-upon-first-use
+
+      * --no-ignore-change-password-upon-first-use
+
+      * --enable-lock-password
+
+      * --disable-lock-password
+
+      * --enable-multi-factor-auth
+
+      * --disable-multi-factor-auth
+
+      * --multi-factor-auth-rule
+
+
+      This will now allow users to set user options via CLI.
+
+      <https://docs.openstack.org/keystone/latest/admin/resource-options.html#user-options>
+
+      '
+  releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml:
+    features:
+    - 'Added the below mentioned parameters to the role, project and domain commands.
+
+
+      * --immutable
+
+      * --no-immutable
+
+
+      This will allow user to set "immutable" resource option.'
+  releasenotes/notes/add_volume_backend_commands_to_volumeV3-145b114e40ab8615.yaml:
+    features:
+    - 'Support of two commands was added in volume v3: "volume backend capability
+
+      show" and "volume backend pool list". These commands are present in v2
+
+      volume, but still absent in v3.
+
+      '
+  releasenotes/notes/address-scope-delete-multi-31c3af73feb31265.yaml:
+    upgrade:
+    - '``address scope delete`` command now accepts multiple address scopes
+
+      in a single command
+
+      '
+  releasenotes/notes/aggregate-list-uuid-column-808a0d051006a5ef.yaml:
+    features:
+    - 'The ``aggregate list`` command will now include the UUIDs of the aggregates
+
+      when the cloud supports it.
+
+      '
+  releasenotes/notes/allow-custom-logging-12d55f8ed859ff8e.yaml:
+    features:
+    - 'Allow custom logging of components
+
+      [Bug `1484660 <https://bugs.launchpad.net/python-openstackclient/+bug/1484660>`_]
+
+      '
+  releasenotes/notes/allow-port-create-with-extra-dhcp-options-c2c40e4002b52e2a.yaml:
+    features:
+    - 'Add ``--extra-dhcp-options`` parameter to the ``port create`` command. The
+
+      neutronclient ``port-create`` command can accept extra DHCP options, add
+
+      it to the openstackclient in order to be consistent.'
+  releasenotes/notes/allow-port-list-with-ip-address-substr-14c5805b241e402f.yaml:
+    features:
+    - 'Add an ``ip-substring`` key to the ``--fixed-ip`` option of the
+
+      ``port list`` command.  This allows filtering ports by a substring
+
+      match of an IP address.
+
+      [Bug `1718605 <https://bugs.launchpad.net/bugs/1718605>`_]'
+  releasenotes/notes/allow-to-add-remove-vm-ports-273593d7cc1982de.yaml:
+    features:
+    - 'Add ``server add port`` and ``server remove port`` commands which enable to
+
+      add/remove ports to/from a server
+
+      [Bug `1678137 <https://bugs.launchpad.net/python-openstackclient/+bug/1678137>`_]
+
+      '
+  releasenotes/notes/allow-to-create-legacy-router-cb4dcb44dde74684.yaml:
+    features:
+    - 'Add ``--no-ha`` option to the ``router create`` command
+
+      [Bug `1675514 <https://bugs.launchpad.net/python-openstackclient/+bug/1675514>`_]
+
+      '
+  releasenotes/notes/allow-to-specify-vm-ip-to-publish-85f7207740c0cc8d.yaml:
+    features:
+    - 'Add ``--fixed-ip-address`` option to the ``server add floating ip`` command
+
+      [Bug `1624524 <https://bugs.launchpad.net/python-openstackclient/+bug/1624524>`_]
+
+      '
+  releasenotes/notes/allow-to-vm-ip-to-add-7721ba64b863fa77.yaml:
+    features:
+    - 'Add ``--fixed-ip-address`` option to the ``server add fixed ip`` command
+
+      [Bug `1678140 <https://bugs.launchpad.net/python-openstackclient/+bug/1678140>`_]
+
+      '
+  releasenotes/notes/always-show-direction-for-sg-rule-130efc39bf67d79a.yaml:
+    deprecations:
+    - 'Deprecate the ``--long`` option for the ``security group list``
+
+      command. This is no longer needed to display all columns.
+
+      '
+    features:
+    - 'By default listing security group rules now shows the direction.
+
+      The ``--long`` argument is now redundant and is now ignored as it
+
+      was only used to display the direction.
+
+      '
+  releasenotes/notes/auto-configure-block-live-migration-437d461c914f8f2f.yaml:
+    features:
+    - 'The ``server migrate`` command will now automatically determine whether
+
+      to use block or shared migration during a live migration operation. This
+
+      requires Compute API microversion 2.25 or greater.
+
+      '
+  releasenotes/notes/auto-no-network-options-f4ddb2bb7544d2f5.yaml:
+    features:
+    - 'The ``server create`` command now accepts two new options, ``--no-network``
+
+      and ``--auto-network``. These are aliases for ``--nic none`` and
+
+      ``--nic auto``, respectively.
+
+      '
+  releasenotes/notes/backup_list_all-projects_option-4bb23e0b9b075cac.yaml:
+    features:
+    - Add ``--all-projects`` option to the ``volume backup list`` command to list
+      volume backups across all projects.
+  releasenotes/notes/better-ipv6-address-suppport-security-group-rules-95272847349982e5.yaml:
+    features:
+    - 'Add ``--ethertype`` option to ``security group rule list`` command.
+
+      Valid values are ``ipv4`` and ``ipv6``.
+
+      '
+    upgrade:
+    - 'Security group rule listings now have the ``Ethertype`` field displayed
+
+      by default to more easily differentiate between IPv4 and IPv6 rules.
+
+      In addition, the ``IP Range`` field of a security group will be
+
+      changed to ``0.0.0.0/0`` for IPv4 and ``::/0`` for IPv6 if no
+
+      value is returned for the address, based on the Ethertype field of
+
+      the rule. For further information see
+
+      [Bug `1735575 <https://bugs.launchpad.net/bugs/1735575>`_]
+
+      '
+  releasenotes/notes/block-storage-x-manageable-list-long-option-a16a4641acfcf781.yaml:
+    upgrade:
+    - 'The ``--detailed`` option of the ``block storage volume manageable list``
+
+      and ``block storage snapshot manageable list`` commands has been deprecated
+
+      in favour of a ``--long`` option. These commands will no longer default to
+
+      detailed output by default.
+
+      '
+  releasenotes/notes/bp-add-locked-reason-425efd2def1144f1.yaml:
+    features:
+    - Add ``--reason`` option to the ``server lock`` command to specify a reason when
+      locking a server. Requires ``–os-compute-api-version`` 2.73 or greater.
+    - Add ``--locked`` option to the ``server list`` command to list only locked servers.
+      Requires ``–os-compute-api-version`` 2.73 or greater.
+    - Add ``--unlocked`` option to the ``server list`` command list only unlocked
+      servers. Requires ``–os-compute-api-version`` 2.73 or greater. [Blueprint `add-locked-reason
+      <https://blueprints.launchpad.net/nova/+spec/add-locked-reason>`_]
+  releasenotes/notes/bp-add-user-id-field-to-the-migrations-table-299b99ccb1f12a1f.yaml:
+    features:
+    - 'Add ``server migration list`` command. This command allows
+
+      users to list the status of ongoing server migrations.
+
+      '
+  releasenotes/notes/bp-address-groups-in-sg-rules-b3b7742e4e6f5745.yaml:
+    features:
+    - 'Add ``--remote-address-group`` option to ``security group rule create``
+
+      command for using an address group as the source/destination in security
+
+      group rules. Also add field ``remote_address_group_id`` to the output of
+
+      ``security group rule show`` and add column ``Remote Address Group`` to
+
+      the output of ``security group rule list``.
+
+      [Blueprint `address-groups-in-sg-rules <https://blueprints.launchpad.net/neutron/+spec/address-groups-in-sg-rules>`_]
+
+      '
+  releasenotes/notes/bp-address-groups-in-sg-rules-e0dc7e889e107799.yaml:
+    features:
+    - Add ``address group create``, ``address group delete``, ``address group list``,
+      ``address group set``, ``address group show`` and ``address group unset`` commands
+      to support Neutron address group CRUD operations. [Blueprint `address-groups-in-sg-rules
+      <https://blueprints.launchpad.net/neutron/+spec/address-groups-in-sg-rules>`_]
+  releasenotes/notes/bp-allow-overwrite-set-options-190a9c6904d53dab.yaml:
+    features:
+    - 'Allow ``--no-fixed-ip`` and ``--no-binding-profile`` options to
+
+      ``port set`` command to be specified when ``--fixed-ip`` and
+
+      ``--binding-profile`` are present.  This allows the list of fixed
+
+      IPs and binding profiles to be cleared and replaced with new values
+
+      in a single command.
+
+      [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+      '
+    - 'Add ``--no-allocation-pool`` and ``--no-host-route`` options to
+
+      ``subnet set`` command that clears the respective values in the
+
+      specified subnet.  This allows new values to replace the entire
+
+      list of existing values in a single command for allocation pools
+
+      and host routes.
+
+      [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+      '
+  releasenotes/notes/bp-application-credential-a7031a043efc4a25.yaml:
+    features:
+    - 'Adds support for creating, reading, and deleting application credentials
+
+      via the ``appication credential`` command. With application credentials, a
+
+      user can grant their applications limited access to their cloud resources.
+
+      Once created, users can authenticate with an application credential by
+
+      using the ``v3applicationcredential`` auth type.
+
+      [`blueprint application-credentials <https://blueprints.launchpad.net/keystone/+spec/application-credentials>`_]
+
+      '
+  releasenotes/notes/bp-backup-snapshot-renamed-for-volume-resource-2d2d13ea8489a61f.yaml:
+    deprecations:
+    - Deprecate commands ``backup create/delete/list/show/restore``. [Blueprint `backup-snapshot-renamed-for-volume-resource
+      <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+    features:
+    - Add new commands ``volume backup create/delete/list/show/restore``. It is used
+      to replace the old commands ``backup create/delete/list/show/restore``. [Blueprint
+      `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+  releasenotes/notes/bp-cinder-command-support-3db775ba331e113d.yaml:
+    features:
+    - 'Add ``--read-only`` and ``--read-write`` options to ``volume set`` command.
+
+      [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+      '
+  releasenotes/notes/bp-cinder-command-support-413b6d80232f8ece.yaml:
+    features:
+    - 'Add ``--type`` and ``--retype-policy`` options to ``volume set`` command.
+
+      [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+
+      '
+  releasenotes/notes/bp-cinder-command-support-7e3ae1fb4cd90407.yaml:
+    features:
+    - Add ``volume host set`` command, it allows a user to enable or disable a volume
+      host. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+  releasenotes/notes/bp-cinder-command-support-82dbadef47454c18.yaml:
+    features:
+    - 'Add ``--default`` option to ``volume type list`` command, in
+
+      order to show which volume type the volume sets as it''s
+
+      default.
+
+      [Blueprint :oscbp:`cinder-command-support`]
+
+      '
+  releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml:
+    features:
+    - Add ``volume transfer request create``, ``volume transfer request delete``,
+      ``volume transfer request show`` and ``volume transfer request accept`` commands
+      in volume v1 and v2. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+  releasenotes/notes/bp-cinder-command-support-ff7acc531baae8c3.yaml:
+    features:
+    - Add ``--bootable``, ``--non-bootable``, ``--read-only`` and ``--read-write``
+      options to ``volume create`` command. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+  releasenotes/notes/bp-extension-show-6f7e31a27dad0dc9.yaml:
+    features:
+    - 'Added ``extension show`` command to display the details of an extension.
+
+      Currently works only for network extensions.
+
+      [Blueprint `extension-show <https://blueprints.launchpad.net/python-openstackclient/+spec/extension-show>`_]
+
+      '
+  releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml:
+    features:
+    - 'From microversion 2.69 the results of ``openstack server list`` and
+
+      ``openstack server show`` may contain missing information in their outputs
+
+      when there are partial infrastructure failure periods in the deployment.
+
+      See `Handling Down Cells`_ for more information on the missing keys/info.
+
+
+      .. _Handling Down Cells: https://developer.openstack.org/api-guide/compute/down_cells.html'
+  releasenotes/notes/bp-implement-network-agents-5eba48796318f094.yaml:
+    features:
+    - Add ``network agent delete``, ``network agent list``, ``network agent show``
+      and ``network agent set`` commands. [Blueprint `implement-network-agents <https://blueprints.launchpad.net/python-openstackclient/+spec/implement-network-agents>`_]
+  releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml:
+    features:
+    - Support bulk deletion and error handling for ``aggregate delete``, ``flavor
+      delete``, ``keypair delete`` and ``service delete`` commands. [Blueprint `multi-argument-compute
+      <https://blueprints.launchpad.net/python-openstackclient/+spec/multi-argument-compute>`_]
+  releasenotes/notes/bp-multi-argument-network-e43e192ac95db94d.yaml:
+    features:
+    - Support bulk deletion for ``subnet pool delete``, ``subnet delete``, ``floating
+      ip delete``, ``security group delete`` and ``security group rule delete``. [Blueprint
+      `multi-argument-network <https://blueprints.launchpad.net/python-openstackclient/+spec/multi-argument-network>`_]
+  releasenotes/notes/bp-network-command-options-2-e7b13a6a09f5d21e.yaml:
+    features:
+    - 'Add ``--description`` option to ``network create`` and
+
+      ``network set`` commands.
+
+      [Blueprint `network-commands-options <https://blueprints.launchpad.net/python-openstackclient/+spec/network-commands-options>`_]
+
+      '
+  releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml:
+    features:
+    - 'Add network dhcp-agent related commands ``network agent add network``,
+
+      ``network agent remove network``, ``network agent list --network`` and
+
+      ``network list --agent`` for adding/removing network to dhcp agent.
+
+      [Blueprint :oscbp:`network-dhcp-adv-commands`]
+
+      '
+  releasenotes/notes/bp-network-l3-adv-commands-cc1df715a184f1b2.yaml:
+    features:
+    - 'Add  ``network agent add router`` and ``network agent remove router``
+
+      commands for adding/removing routers to network l3 agents.
+
+      [Blueprint :oscbp:`network-l3-commands`]
+
+      '
+    - 'Add ``--router`` option to ``network agent list`` to filter by router,
+
+      and ``--agent`` option to ``router list`` command to filter by agent.
+
+      [Blueprint :oscbp:`network-l3-commands`]
+
+      '
+  releasenotes/notes/bp-network-segment-range-management-0abf03fe03eea149.yaml:
+    features:
+    - Add ``network segment range create``, ``network segment range delete``, ``network
+      segment range list``, ``network segment range show`` and ``network segment range
+      set`` commands. [Blueprint `network-segment-range-management <https://blueprints.launchpad.net/neutron/+spec/network-segment-range-management>`_]
+  releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml:
+    features:
+    - Update ``--binding-profile`` option on the ``port create`` and ``port set``
+      commands to support JSON input for more advanced binding profile data. [Blueprint
+      :oscbp:`neutron-client`]
+    - Add ``--enable-port-security`` and ``--disable-port-security`` options on the
+      ``network create`` and ``network set`` commands. This supports setting the default
+      port security for ports created on a network. [Blueprint :oscbp:`neutron-client`]
+    - Add ``geneve`` choice to the  ``network create`` command ``--provider-network-type``
+      option. [Blueprint :oscbp:`neutron-client`]
+    - Add ``--device-owner`` option to the ``port list`` command to enable listing
+      ports based on device owner. [Blueprint :oscbp:`neutron-client`]
+  releasenotes/notes/bp-neutron-client-descriptions-a80902b4295843cf.yaml:
+    features:
+    - 'Add ``--description`` option to ``floating ip create`` command.
+
+      [Blueprint :oscbp:`neutron-client-descriptions`]
+
+      '
+    - 'Add ``--description`` option to ``router set`` and
+
+      ``router create`` commands.
+
+      [Blueprint :oscbp:`network-commands-options`]
+
+      '
+  releasenotes/notes/bp-neutron-client-descriptions-b65dd776f78b5a73.yaml:
+    features:
+    - 'Add ``--description`` option to ``security group rule create`` command.
+
+      [Blueprint :oscbp:`network-commands-options`]
+
+      '
+    - 'Add ``--description`` option to ``port set`` and
+
+      ``port create`` commands.
+
+      [Blueprint :oscbp:`neutron-client-descriptions`]
+
+      '
+  releasenotes/notes/bp-neutron-client-metering-1ee703a48343ece1.yaml:
+    features:
+    - 'Add support for network metering commands:
+
+      ``network meter create``, ``network meter delete``,
+
+      ``network meter show``, ``network meter list``
+
+      [Blueprint :oscbp:`neutron-client-metering`]
+
+      '
+  releasenotes/notes/bp-neutron-client-metering-6f8f9527c2a797fd.yaml:
+    features:
+    - 'Add meter rules commands for ``network meter rule create``,
+
+      ``network meter rule delete``, ``network meter rule list``,
+
+      and ``network meter rule show``.
+
+      [Blueprint :oscbp:`neutron-client-metering`]
+
+      '
+  releasenotes/notes/bp-neutron-client-rbac-bbd7b545b50d2bdf.yaml:
+    features:
+    - Add ``network rbac list``, ``network rbac show``, ``network rbac create``, ``network
+      rbac delete`` and ``network rbac set`` commands. [Blueprint `neutron-client-rbac
+      <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-rbac>`_]
+  releasenotes/notes/bp-neutron-client-tag-ff24d13e5c70e052.yaml:
+    features:
+    - "Added support for ``tags`` to the following resources:\n``network``, ``subnet``,\
+      \ ``port``, ``router`` and ``subnet pool``.\n[Blueprint :oscbp:`neutron-client-tag`]\n\
+      \n- Add ``--tag`` and ``--no-tag`` options to corresponding \"create\" commands.\n\
+      - Add ``--tag`` and ``--no-tag`` options to corresponding \"set\" commands.\n\
+      - Add ``--tag`` and ``--all-tag`` options to corresponding \"unset\" commands.\n\
+      \  (``network unset`` command is introduced to support the tag operation)\n\
+      - Add ``--tags``, ``--any-tags``, ``--not-tags`` and ``--not-any-tags``\n  options\
+      \ to corresponding \"list\" commands.\n"
+  releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml:
+    features:
+    - 'Add support for attaching and removing qos policy to floating IPs.
+
+
+      Add option ``--qos-policy`` to the ``floating ip create`` and
+
+      ``floating ip set`` commands to add qos policy to a floating IP.
+
+
+      Add option ``--no-qos-policy`` to the ``floating ip set`` and option
+
+      ``--qos-policy`` to the ``floating ip unset`` command to remove the
+
+      qos policy from a floating IP.
+
+      '
+  releasenotes/notes/bp-project-tags-b544aef9672d415b.yaml:
+    features:
+    - "Add ``--tag`` option to ``project create`` command,  ``--tag``, ``--clear-tags``,\
+      \ and\n``--remove-tag`` options to ``project set`` command. Add ``--tags``,\
+      \ ``--tags-any``, \n``--not-tags``, and ``--not-tags-any`` options to ``project\
+      \ list`` command to filter\nlist results by different projects based on their\
+      \ tags.\n[`blueprint project-tags <https://blueprints.launchpad.net/keystone/+spec/project-tags>`_]\n"
+  releasenotes/notes/bp-routed-networks-3b502faa5cd96807.yaml:
+    features:
+    - Add ``network segment create``, ``network segment delete`` and ``network segment
+      set`` commands. In addition, the ``network segment list`` and ``network segment
+      show`` commands are no longer beta commands and the ``--network-segment`` option
+      on the ``subnet create`` command is no longer a beta command option. [Blueprint
+      `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
+  releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml:
+    features:
+    - Add ``network segment list`` and ``network segment show`` commands. These are
+      beta commands and subject to change. Use global option ``--os-beta-command``
+      to enable these commands. [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
+  releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml:
+    features:
+    - Add ``--network-segment`` option to the ``subnet create`` command. This is a
+      beta command option and subject to change. Use global option ``--os-beta-command``
+      to enable this option. [Blueprint `routed-networks <https://blueprints.launchpad.net/neutron/+spec/routed-networks>`_]
+  releasenotes/notes/bp-support-multi-add-remove-9516f72cfacea11a.yaml:
+    features:
+    - 'Add support to add/remove multi users by ``group add/remove user`` command.
+
+      [Blueprint  :oscbp:`support-multi-add-remove`]
+
+      '
+  releasenotes/notes/bp-support-no-property-in-aggregate-b74a42e00a65d14a.yaml:
+    features:
+    - 'Add ``--no-property`` option to ``aggregate set`` command.
+
+      This allows the property list to be cleared and replaced with
+
+      new values in a single command.
+
+      [Blueprint `support-no-property-in-aggregate <https://blueprints.launchpad.net/python-openstackclient/+spec/support-no-property-in-aggregate>`_]
+
+      '
+  releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-16e864223d51b50a.yaml:
+    features:
+    - Add ``--availability-zone`` option to ``server unshelve`` command to enable
+      users to specify an availability zone during unshelve of a shelved offloaded
+      server. Note that it requires ``--os-compute-api-version 2.77`` or greater.
+      [Blueprint `support-specifying-az-when-restore-shelved-server <https://blueprints.launchpad.net/nova/+spec/support-specifying-az-when-restore-shelved-server>`_]
+  releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-9179045f04815bbb.yaml:
+    features:
+    - 'Add ``--disable-delete-on-termination`` and
+
+      ``--enable-delete-on-termination`` options to the ``server add volume``
+
+      command to indicate when to delete the attached volume when the server
+
+      is deleted.
+
+      Note that it requires ``--os-compute-api-version 2.79`` or greater.
+
+      [Blueprint support-specifying-az-when-restore-shelved-server `<https://blueprints.launchpad.net/nova/+spec/support-delete-on-termination-in-server-attach-volume>`_]
+
+      '
+  releasenotes/notes/bp-unified-limits-58f166401534a4ff.yaml:
+    features:
+    - 'Add ``registered limit`` commands for managing registered limits in Keystone.
+
+      Registered limits define limits of resources for projects to assume by default.
+
+      [`bp unified-limits <https://blueprints.launchpad.net/keystone/+spec/unified-limit>`_]
+
+      '
+  releasenotes/notes/bp-unified-limits-6c5fdb1c26805d86.yaml:
+    features:
+    - 'Add ``limit`` commands for managing project-specific limits in keystone.
+
+      Limits define limits of resources for projects to consume once a limit
+
+      has been registered.
+
+      [`bp unified-limits <https://blueprints.launchpad.net/keystone/+spec/unified-limit>`_]
+
+      '
+  releasenotes/notes/bp-unshelve-to-host-9ce4b7abf81aeedf.yaml:
+    features:
+    - Add ``--host`` and ``--no-availability-zone`` options to the ``server unshelve``
+      command to enable administrators to specify a destination host or unset the
+      availability zone during a server unshelve, respectively. Both options require
+      the server to be shelved offload and ``--os-compute-api-version 2.91`` or greater.
+  releasenotes/notes/bp-whitelist-extension-for-app-creds-9afd5009b374190b.yaml:
+    features:
+    - '[`blueprint whitelist-extension-for-app-creds <https://blueprints.launchpad.net/keystone/+spec/whitelist-extension-for-app-creds>`_]
+
+      Added support for creating access rules as an attribute of application
+
+      credentials as well as for listing, showing, and deleting access rules.
+
+      '
+  releasenotes/notes/bug-1204956-af47c7f34ecc19c3.yaml:
+    features:
+    - Supported to fetch network project default quota with command ``quota show --default``.
+      [Bug `1204956 <https://bugs.launchpad.net/neutron/+bug/1204956>`_]
+  releasenotes/notes/bug-1411190-live-migration-host-655ae6befa6a3de2.yaml:
+    deprecations:
+    - "The ``--live`` option on the ``openstack server migrate`` command has\nbeen\
+      \ deprecated and is being replaced with two new options:\n\n* ``--live-migration``:\
+      \ This will signal that the migration is a live\n  migration.\n* ``--host``:\
+      \ This can be used to request a target host for the live\n  migration but requires\
+      \ ``--os-compute-api-version`` 2.30 or greater\n  so the requested host can\
+      \ be validated by the scheduler.\n\nThe ``--live`` option is problematic in\
+      \ that it requires a host and\nprior to compute API version 2.30, specifying\
+      \ a host during live migration\nwill bypass validation by the scheduler which\
+      \ could result in failures to\nactually migrate the server to the specified\
+      \ host or over-subscribe the\nhost.\n\nThe ``--live`` and ``--host`` options\
+      \ are mutually exclusive. Furthermore,\nif both the ``--live`` and ``--live-migration``\
+      \ options are used the\n``--live-migration`` option takes priority.\n"
+    fixes:
+    - '`Bug 1411190`_ has been fixed by providing a ``--live-migration`` and
+
+      ``--host`` option to the ``openstack server migrate`` command.
+
+
+      .. _Bug 1411190: https://bugs.launchpad.net/python-openstackclient/+bug/1411190
+
+      '
+  releasenotes/notes/bug-1475831-3caafd724d4ed644.yaml:
+    fixes:
+    - 'Some compute quotas were not being set
+
+      [Bug `1475831 <https://bugs.launchpad.net/bugs/1475831>`_]
+
+      '
+  releasenotes/notes/bug-1486597-857e20262c038514.yaml:
+    features:
+    - 'Add ``project unset`` command for Identity v2
+
+      [Bug `1486597 <https://bugs.launchpad.net/bugs/1486597>`_]
+
+      '
+  releasenotes/notes/bug-1499657-eeb260849febacf3.yaml:
+    fixes:
+    - 'Fix ``--parents`` and ``--children`` options in ``project show`` command.
+
+      [Bug `1499657 <https://bugs.launchpad.net/python-openstackclient/+bug/1499657>`_]
+
+      '
+  releasenotes/notes/bug-1513894-6d2f05db6e1df744.yaml:
+    features:
+    - 'Add ``--use-prefix-delegation`` option to the ``subnet create`` command to
+
+      specify ''Prefix Delegation'' as a subnetpool when creating subnets.
+
+      [Bug `1513894 <https://bugs.launchpad.net/bugs/1513894>`_]
+
+      '
+  releasenotes/notes/bug-1516661-757ef629f899cca3.yaml:
+    features:
+    - 'Add ``image set --activate|--deactivate`` options (Image v2 only)
+
+      [Bug `1516661 <https://bugs.launchpad.net/bugs/1516661>`_]
+
+      '
+  releasenotes/notes/bug-1517134-9efecb257910989c.yaml:
+    features:
+    - 'Add ``--project-domain`` option to ``image create`` and ``image set`` commands
+
+      (Image v2 only)
+
+      [Bug `1517134 <https://bugs.launchpad.net/bugs/1517134>`_]
+
+      '
+  releasenotes/notes/bug-1517386-1c0aad8e3203b02b.yaml:
+    fixes:
+    - 'Add `--all` for `snapshot list`
+
+      [Bug `1517386 <https://bugs.launchpad.net/bugs/1517386>`_]
+
+      '
+  releasenotes/notes/bug-1518059-e2dbe6e4b2473f10.yaml:
+    fixes:
+    - 'Fix the ``--block-migration`` and ``--shared-migration`` options for
+
+      ``server migrate`` to send the correct values to the Compute API.
+
+      [Bug `1518059 <https://bugs.launchpad.net/bugs/1518059>`_]:
+
+      '
+  releasenotes/notes/bug-1519181-932c1ff07ef16666.yaml:
+    fixes:
+    - 'Add Status column to default ``image list`` output (v1 and v2)
+
+      [Bug `1519181 <https://bugs.launchpad.net/bugs/1519181>`_]
+
+      '
+  releasenotes/notes/bug-1519502-d534db6c18adef20.yaml:
+    upgrade:
+    - The ``ip floating create`` command now uses Network v2 when enabled [Bug `1519502
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+  releasenotes/notes/bug-1519502-f72236598d14d350.yaml:
+    features:
+    - Command ``ip floating delete`` is now available for neutron network. [Bug `1519502
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+    - Command ``ip floating list`` is now available for neutron network. [Bug `1519502
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+    - Add command ``ip floating show`` for neutron and nova network. [Bug `1519502
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1519502>`_]
+  releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml:
+    features:
+    - 'Add ``router`` commands ``create``, ``delete``, ``list``, ``set``, ``show``
+
+      [Bug `1519503 <https://bugs.launchpad.net/bugs/1519503>`_]
+
+      '
+  releasenotes/notes/bug-1519510-3cde4643b33ebb7a.yaml:
+    other:
+    - 'Drop Python 2.6 support
+
+      [Bug `1519510 <https://bugs.launchpad.net/bugs/1519510>`_]
+
+      '
+  releasenotes/notes/bug-1519511-65b8901ae6ea2e63.yaml:
+    features:
+    - The ``security group create``, ``security group set`` and ``security group show``
+      commands now uses Network v2 when enabled which results in a more detailed output
+      for network security group rules. [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+    fixes:
+    - The ``security group create`` command now uses Network v2 when enabled which
+      allows the security group description to be created with an empty value. In
+      addition, the ``tenant_id`` field changed to ``project_id`` to match the ``security
+      group show`` command output. [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+  releasenotes/notes/bug-1519511-65d8d21dde31e5e2.yaml:
+    features:
+    - Add ``--project`` and ``--project-domain`` options to the ``security group create``
+      command for Network v2. [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+  releasenotes/notes/bug-1519511-74bab0e0d32db043.yaml:
+    fixes:
+    - 'Ignore the ``security group list`` command ``--all-projects`` option
+
+      for Network v2 since security groups will be displayed for all projects
+
+      by default (admin only).
+
+      [Bug `1519511 <https://bugs.launchpad.net/bugs/1519511>`_]
+
+      '
+  releasenotes/notes/bug-1519512-4231ac6014109142.yaml:
+    upgrade:
+    - The ``security group rule create`` command now uses Network v2 when enabled
+      which results in a more detailed output for network security group rules that
+      matches the ``security group rule show`` command. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+  releasenotes/notes/bug-1519512-48624c5a32432a47.yaml:
+    features:
+    - 'Add support for ``security group rule show`` command.
+
+      [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+      '
+  releasenotes/notes/bug-1519512-48d98f09e44220a3.yaml:
+    features:
+    - Add ``--ingress``, ``--egress``, ``--ethertype``, ``--project`` and ``--project-domain``
+      options to the ``security group rule create`` command for Network v2 only. These
+      options enable ``egress`` and ``IPv6`` security group rules along with setting
+      the project. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+  releasenotes/notes/bug-1519512-65df002102b7fb99.yaml:
+    features:
+    - The ``security group rule list`` command now uses Network v2 when enabled which
+      results in ``egress`` security group rules being displayed. The ``--long`` option
+      was also added for Network v2 to display direction and ethertype information.
+      In addition, security group rules for all projects will be displayed when the
+      ``group`` argument is not specified (admin only). This is done by default when
+      using Network v2, but requires the new ``--all-projects`` option when using
+      Compute v2. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+    fixes:
+    - The ``security group rule list`` command no longer ignores the ``group`` argument
+      when it is set to an empty value. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+  releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml:
+    fixes:
+    - 'Make ``security group rule list`` group argument optional to list all
+
+      security groups
+
+      [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+
+      '
+  releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml:
+    features:
+    - Add ``--icmp-type`` and ``--icmp-code`` options to the ``security group rule
+      create`` command for Network v2 only. These options can be used to set ICMP
+      type and code for ICMP IP protocols. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+    - The following Network v2 IP protocols are supported by the ``security group
+      rule create`` command ``--protocol`` option, ``ah``, ``dccp``, ``egp``, ``esp``,
+      ``gre``, ``igmp``, ``ipv6-encap``, ``ipv6-frag``, ``ipv6-icmp``, ``ipv6-nonxt``,
+      ``ipv6-opts``, ``ipv6-route``, ``ospf``, ``pgm``, ``rsvp``, ``sctp``, ``udplite``,
+      ``vrrp`` and integer representations [0-255]. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+    - The ``security group rule list`` command supports displaying the ICMP type and
+      code for security group rules with the ICMP IP protocols. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+    upgrade:
+    - Changed the ``security group rule create`` command ``--proto`` option to ``--protocol``.
+      Using the ``--proto`` option is still supported, but is no longer documented
+      and may be deprecated in a future release. [Bug `1519512 <https://bugs.launchpad.net/bugs/1519512>`_]
+  releasenotes/notes/bug-1520003-505af921c8afffc9.yaml:
+    fixes:
+    - 'Add remote security group to ``os security group rule list``
+
+      [Bug `1520003 <https://bugs.launchpad.net/bugs/1520003>`_]
+
+      '
+  releasenotes/notes/bug-1520115-0367e1c8917dc912.yaml:
+    fixes:
+    - 'Fix ``--public|--private`` options for ``volume type create`` command
+
+      to correctly pass privacy argument to client library
+
+      [Bug `1520115 <https://bugs.launchpad.net/bugs/1520115>`_]
+
+      '
+  releasenotes/notes/bug-1520541-44d45e4693089c03.yaml:
+    fixes:
+    - 'Fix ``volume delete`` command to delete all specified volumes rather
+
+      than only the last volume
+
+      [Bug `1520541 <https://bugs.launchpad.net/bugs/1520541>`_]
+
+      '
+  releasenotes/notes/bug-1521492-89b972c6362940a5.yaml:
+    fixes:
+    - 'Change ``server list --flavor`` to now accept flavor ID or name
+
+      [Bug `1521492 <https://bugs.launchpad.net/bugs/1521492>`_]
+
+      '
+  releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml:
+    fixes:
+    - 'Change ``server list --image`` to now accept image ID or name
+
+      [Bug `1521492 <https://bugs.launchpad.net/bugs/1521492>`_]
+
+      '
+  releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml:
+    features:
+    - 'Add ``--src-group`` option to ``security group rule create`` to include a
+
+      ''remote'' security group rule.
+
+      [Bug `1522969 <https://bugs.launchpad.net/bugs/1522969>`_]
+
+      '
+  releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml:
+    fixes:
+    - 'Change the ``project set --domain`` option to use the argument as a lookup
+
+      for locating projects in non-default domains.
+
+      [Bug `1524456 <https://bugs.launchpad.net/bugs/1524456>`_]
+
+      '
+  releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml:
+    fixes:
+    - 'Fix case sensitivity when showing object-store properties.
+
+      [Bug `1525805 <https://bugs.launchpad.net/bugs/1525805>`_]
+
+      '
+  releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml:
+    other:
+    - Change the ``--owner`` option to ``--project`` in ``image create`` and ``image
+      set`` commands.  ``--owner`` is deprecated and no longer documented but is still
+      accepted; a warning message will be shown if it is used. [Bug `1527833 <https://bugs.launchpad.net/bugs/1527833>`_]
+  releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml:
+    fixes:
+    - 'Support non-interactive user password update
+
+      [Bug `1531360 <https://bugs.launchpad.net/bugs/1531360>`_]
+
+      '
+  releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml:
+    features:
+    - 'Add volume support to ``os availability zone list``
+
+      [Bug `1532945 <https://bugs.launchpad.net/bugs/1532945>`_]
+
+
+      * New ``--compute`` option to only list compute availability zones.
+
+      * New ``--volume`` option to only list volume availability zones.
+
+      '
+  releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml:
+    features:
+    - 'Add network support to ``os availability zone list``
+
+      [Bug `1534202 <https://bugs.launchpad.net/bugs/1534202>`_]
+
+
+      * New ``--network`` option to only list network availability zones.
+
+      '
+  releasenotes/notes/bug-1535213-c91133586e07d71c.yaml:
+    fixes:
+    - 'Support a new ``--state`` option for ``volume set`` command that
+
+      changes the state of a volume.
+
+      [Bug `1535213 <https://bugs.launchpad.net/bugs/1535213>`_]
+
+      '
+  releasenotes/notes/bug-1535239-767e6cf1990eda01.yaml:
+    fixes:
+    - 'Support a new ``--state`` option for ``snapshot set`` command that
+
+      changes the state of a snapshot.
+
+      [Bug `1535239 <https://bugs.launchpad.net/bugs/1535239>`_]
+
+      '
+  releasenotes/notes/bug-1535704-d6f013bfa22ab668.yaml:
+    fixes:
+    - 'Add ``--bootable`` and ``--non-bootable`` options to ``os volume set``
+
+      command to mark volume as bootable or non-bootable.
+
+      [Bug `1535704 <https://bugs.launchpad.net/bugs/1535704>`_]'
+  releasenotes/notes/bug-1536479-d1f03ed2177d06ed.yaml:
+    fixes:
+    - '``--pool-prefix`` option made required for ``subnet pool create``
+
+      [Bug `1536479 <https://bugs.launchpad.net/bugs/1536479>`_]
+
+      '
+  releasenotes/notes/bug-1538372-ef3a30298357f972.yaml:
+    features:
+    - 'Add support for the `server dump create` command
+
+      [Bug `1538372 <https://bugs.launchpad.net/python-openstackclient/+bug/1538372>`_]
+
+      '
+  releasenotes/notes/bug-1540656-f7b7b7e3feef2440.yaml:
+    features:
+    - The ``security group rule create`` command now supports a security group name
+      for the ``--src-group`` option. [Bug `1540656 <https://bugs.launchpad.net/bugs/1540656>`_]
+  releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml:
+    features:
+    - 'Add ``--limit`` option to ``image list`` to limit the number of images
+
+      in output.
+
+      [Bug `1540988 <https://bugs.launchpad.net/bugs/1540988>`_]
+
+      '
+    - 'Add ``--marker`` option to ``image list`` to handle paginate requests.
+
+      [Bug `1540988 <https://bugs.launchpad.net/bugs/1540988>`_]
+
+      '
+  releasenotes/notes/bug-1542171-fde165df53216726.yaml:
+    features:
+    - 'Add ``server group create``, ``server group delete``,
+
+      ``server group list``, ``server group show`` commands.
+
+      [Bug `1542171 <https://bugs.launchpad.net/python-openstackclient/+bug/1542171>`_]
+
+      [Blueprint `nova-server-group-support <https://blueprints.launchpad.net/python-openstackclient/+spec/nova-server-group-support>`_]
+
+      '
+  releasenotes/notes/bug-1542359-181d28db21a2358a.yaml:
+    features:
+    - 'Add ``subnet show`` command.
+
+      [Bug `1542359 <https://bugs.launchpad.net/bugs/1542359>`_]
+
+      '
+  releasenotes/notes/bug-1542362-ddad607f6d3025f0.yaml:
+    features:
+    - 'Add ``subnet delete`` command to openstack-client.
+
+      [Bug `1542362 <https://bugs.launchpad.net/python-openstackclient/+bug/1542362>`_]
+
+      '
+  releasenotes/notes/bug-1542364-5d1e93cfd24f0b65.yaml:
+    features:
+    - 'Add ``subnet create`` command.
+
+      [Bug `1542364 <https://bugs.launchpad.net/bugs/1542364>`_]
+
+      '
+  releasenotes/notes/bug-1543214-959aee7830db2b0d.yaml:
+    fixes:
+    - 'The ``token issue`` can now return an unscoped token. If a `project` or `domain`
+
+      target scope are not specified, an unscoped token will be returned.
+
+      [Bug `1543214 <https://bugs.launchpad.net/bugs/1543214>`_]
+
+      '
+  releasenotes/notes/bug-1543222-6f8579344ff5c958.yaml:
+    fixes:
+    - Keystone V3 `user password set` is a self-service operation. It should not required
+      a scoped token as it is not considered a `scoped operation`. [Bug `1543222 <https://bugs.launchpad.net/bugs/1543222>`_]
+  releasenotes/notes/bug-1543226-7d885ecaa3715415.yaml:
+    features:
+    - 'Add ``token revoke`` command for Identity v3
+
+      [Bug `1543226 <https://bugs.launchpad.net/bugs/1543226>`_]
+
+      '
+  releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml:
+    features:
+    - Command ``network delete`` is now available for nova network. [Bug `1543672
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+    - Command ``network list`` is now available for nova network. [Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+    - Command ``network show`` is now available for nova network. [Bug `1543672 <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+    - Command ``network create`` is now available for nova network. [Bug `1543672
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1543672>`_]
+  releasenotes/notes/bug-1544586-0e6ca9a09dac0726.yaml:
+    features:
+    - Add ``subnet pool create`` and ``subnet pool set`` commands. [Bug `1544586 <https://bugs.launchpad.net/python-openstackclient/+bug/1544586>`_]
+      [Bug `1544591 <https://bugs.launchpad.net/python-openstackclient/+bug/1544591>`_]
+  releasenotes/notes/bug-1544586-0fe19a567d3e31fc.yaml:
+    features:
+    - Add ``--share`` and ``--default`` options to ``subnet pool create`` and ``--default``
+      option to ``subnet pool set`` [Bug `1544586 <https://bugs.launchpad.net/python-openstackclient/+bug/1544586>`_]
+      [Bug `1544591 <https://bugs.launchpad.net/python-openstackclient/+bug/1544591>`_]
+  releasenotes/notes/bug-1544587-ec3ca453c1340b4e.yaml:
+    features:
+    - Add support for ``subnet pool delete`` command. [Bug `1544587 <https://bugs.launchpad.net/python-openstackclient/+bug/1544587>`_]
+  releasenotes/notes/bug-1544589-b9f669ef71aa5e57.yaml:
+    features:
+    - Add support for ``subnet pool list`` command. [Bug `1544589 <https://bugs.launchpad.net/python-openstackclient/+bug/1544589>`_]
+  releasenotes/notes/bug-1544590-8cf42954e28c2f42.yaml:
+    features:
+    - Add support for ``subnet pool show`` command. [Bug `1544590 <https://bugs.launchpad.net/python-openstackclient/+bug/1544590>`_]
+  releasenotes/notes/bug-1545537-12bbf01d2280dd2f.yaml:
+    features:
+    - 'Add provider network options ``--provider-network-type``,
+
+      ``--provider-physical-network`` and ``--provider-segment``
+
+      to the ``network create`` and ``network set`` commands.
+
+      These options are available for NetworkV2 only.
+
+      [Bug `1545537 <https://bugs.launchpad.net/bugs/1545537>`_]'
+  releasenotes/notes/bug-1545537-4fa72fbfbbe3f31e.yaml:
+    features:
+    - 'Add ``--transparent-vlan`` and ``--no-transparent-vlan`` options to
+
+      ``network create`` and ``network set`` commands to add/remove VLAN
+
+      transparency attributes from networks.
+
+      This option is available in Network V2 only.
+
+      [Bug `1545537 <https://bugs.launchpad.net/bugs/1545537>`_]'
+  releasenotes/notes/bug-1545537-7a66219d263bb1e5.yaml:
+    features:
+    - 'Add external network options ``--external|--internal`` and ``--external``
+
+      suboptions ``--default|--no-default`` to the ``network create`` and
+
+      ``network set`` commands.
+
+      These options are available for Network version 2 only.
+
+      [Bug `1545537 <https://bugs.launchpad.net/bugs/1545537>`_]'
+  releasenotes/notes/bug-1545609-bdc1efc17214463b.yaml:
+    fixes:
+    - 'Fixed ``openstack command list`` to display properly
+
+      [Bug `1545609 <https://bugs.launchpad.net/python-openstackclient/+bug/1545609>`_]
+
+      '
+  releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml:
+    fixes:
+    - Command ``flavor set/unset`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+    - Command ``security group set`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+    - Command ``compute agent set`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+    - Command ``aggregate set`` now outputs nothing. [Bug `1546065 <https://bugs.launchpad.net/python-openstackclient/+bug/1546065>`_]
+  releasenotes/notes/bug-1549410-8df3a4b12fe13ffa.yaml:
+    features:
+    - 'Add ``--private-key`` option for ``keypair create`` command to specify the
+
+      private key file to save when a keypair is created, removing the need to
+
+      copy the output and paste it into a new file. This is a convenient way
+
+      to save private key in OSC interactive mode.
+
+      [Bug `1549410 <https://bugs.launchpad.net/python-openstackclient/+bug/1549410>`_]
+
+      '
+  releasenotes/notes/bug-1550999-5e352a71dfbc828d.yaml:
+    features:
+    - 'Adds ``volume service list`` command.
+
+      [Bug `1550999 <https://bugs.launchpad.net/python-openstackclient/+bug/1550999>`_]
+
+      '
+  releasenotes/notes/bug-1554877-7f8479791eab45b7.yaml:
+    features:
+    - 'Add ``--image-property`` option to ``volume set`` and ``volume unset`` commands
+
+
+      Image properties are copied when a volume is created from an image.
+
+      The properties are immutable on the image itself but may be updated
+
+      or removed from the volume created from that image.
+
+
+      [Bug `1554877 <https://bugs.launchpad.net/python-openstackclient/+bug/1554877>`_]
+
+      [Bug `1554879 <https://bugs.launchpad.net/python-openstackclient/+bug/1554879>`_]
+
+      '
+  releasenotes/notes/bug-1554886-8e5249a655e7e7b6.yaml:
+    features:
+    - 'Add ``volume transfer request list`` command
+
+      [:lpbug:`1554886`]
+
+      '
+  releasenotes/notes/bug-1554889-32ba8d4bfb0f5f3d.yaml:
+    features:
+    - 'Add ``--project`` and ``--project-domain`` options to ``volume type set``
+
+      and ``volume type unset`` commands
+
+
+      Use the ``--project`` option to restrict a volume type to a specific project.
+
+      Volume types are public by default, restricted volume types should be made
+
+      private with the ``--private`` option to the ``volume create`` command.
+
+
+      [Bug `1554889 <https://bugs.launchpad.net/python-openstackclient/+bug/1554889>`_]
+
+      [Bug `1554890 <https://bugs.launchpad.net/python-openstackclient/+bug/1554890>`_]
+
+      '
+  releasenotes/notes/bug-1556719-d2dcf61acf87e856.yaml:
+    fixes:
+    - Command ``network delete`` will delete as many networks as possible, log and
+      report failures in the end. [Bug `1556719 <https://bugs.launchpad.net/python-openstackclient/+bug/1556719>`_]
+      [Bug `1537856 <https://bugs.launchpad.net/python-openstackclient/+bug/1537856>`_]
+  releasenotes/notes/bug-1556929-edd78cded88ecdc9.yaml:
+    features:
+    - Add ``host set`` command [Bug `1556929 <https://bugs.launchpad.net/python-openstackclient/+bug/1556929>`_]
+  releasenotes/notes/bug-1559866-733988f5dd5b07bb.yaml:
+    features:
+    - Add ``aggregate unset`` command [Bug `1559866 <https://bugs.launchpad.net/python-openstackclient/+bug/1559866>`_]
+  releasenotes/notes/bug-1560157-bce572f58b43efa1.yaml:
+    fixes:
+    - Fixed SSL/TLS verification for Network v2 commands. The commands were ignoring
+      the ``--insecure`` and ``--os-cacert`` options and the ``OS_CACERT`` environment
+      variable which caused them to fail with ``An SSL error occurred.`` when authenticating
+      using SSL/TLS. [Bug `1560157 <https://bugs.launchpad.net/python-openstackclient/+bug/1560157>`_]
+  releasenotes/notes/bug-1561599-d5f541f08ae6274a.yaml:
+    fixes:
+    - When performing ``domain show``, ``project show`` or ``user show``, peek into
+      the user token to determine the ID or the resource (if supplied with only a
+      name). This should make finding information about the user and their project
+      easier for non-admin users. [Bug `1561599 <https://bugs.launchpad.net/bugs/1561599>`_]
+  releasenotes/notes/bug-1561838-3a006a8263d7536d.yaml:
+    features:
+    - Support X.latest format for OS_COMPUTE_API_VERSION in order to talk with the
+      latest nova microversion API, that is very helpful shortcut usage to use new
+      nova side features. [Bug `1561838 <https://bugs.launchpad.net/python-openstackclient/+bug/1561838>`_]
+  releasenotes/notes/bug-1564460-ab7ad35c02392cb4.yaml:
+    fixes:
+    - Fixed the ``--route`` option on the ``router set`` command which did not properly
+      format the new routes to set resulting in a ``Bad Request`` error. In addition,
+      the ``router create``, ``router list`` and ``router show`` command output for
+      routes was fixed to improve readability and to align with the ``--route`` option
+      on the ``router set`` command. [Bug `1564460 <https://bugs.launchpad.net/bugs/1564460>`_]
+  releasenotes/notes/bug-1565034-dd404bfb42d7778d.yaml:
+    fixes:
+    - Added ``--no-route`` to the ``router set`` command. Deprecated ``--clear-routes``.
+      [Bug `1565034 <https://bugs.launchpad.net/bugs/1565034>`_]
+  releasenotes/notes/bug-1565112-e0cea9bfbcab954f.yaml:
+    features:
+    - Add global options ``os-cert`` and ``--os-key`` to support client certificate/key.  Environment
+      variables ``OS_CERT`` and ``OS_KEY``, as well as the ``cert`` and ``key`` values
+      in clouds.yaml may also be used [Bug `1565112 <https://bugs.launchpad.net/bugs/1565112>`_]
+  releasenotes/notes/bug-1566090_64726dc7df5b1572.yaml:
+    features:
+    - '``openstack floating ip`` now provides ``Floating Network`` and
+
+      ``Project`` to identify to which network and project the
+
+      floating-ip belongs to.
+
+      [Bug `1566090 <https://bugs.launchpad.net/bugs/1566090>`_]
+
+      '
+  releasenotes/notes/bug-1566269-2572bca9157ca107.yaml:
+    features:
+    - Add ``address scope create``, ``address scope delete``, ``address scope list``,
+      ``address scope set`` and ``address scope show`` commands. [Bug `1566269 <https://bugs.launchpad.net/python-openstackclient/+bug/1566269>`_]
+  releasenotes/notes/bug-1569480-c52e330548bfbd78.yaml:
+    fixes:
+    - Fixed ``subnet pool list`` command to properly disply the list of subnet pool
+      prefixes in the ``Prefixes`` column. This fix is consistent with the ``subnet
+      pool create`` and ``subnet pool show`` command output. [Bug `1569480 <https://bugs.launchpad.net/bugs/1569480>`_]
+  releasenotes/notes/bug-1571812-49cdce4df5f3d481.yaml:
+    upgrade:
+    - 'Deprecate global option ``--profile`` in favor of ``--os-profile``.
+
+
+      ``--profile`` interferes with existing command options with the same name.
+
+      Unfortunately it appeared in a release so we must follow the deprecation
+
+      process and wait one year (April 2017) before removing it.
+
+
+      [Bug `1571812 <https://bugs.launchpad.net/python-openstackclient/+bug/1571812>`_]
+
+      '
+  releasenotes/notes/bug-1572228-03638a7adec5da8b.yaml:
+    fixes:
+    - Fixed ``network create``, ``network show`` and ``network list`` commands to
+      correctly display the router type in the ``router:external`` and ``Router Type``
+      columns. [Bug `1572228 <https://bugs.launchpad.net/bugs/1572228>`_]
+  releasenotes/notes/bug-1572733-874b37a7fa8292d0.yaml:
+    fixes:
+    - The ``quota show`` command ``<project/class>`` argument is now optional. If
+      not specified, the user's current project is used. This allows non-admin users
+      to show quotas for their current project. [Bug `1572733 <https://bugs.launchpad.net/bugs/1572733>`_]
+  releasenotes/notes/bug-1575461-3fed33e53795684a.yaml:
+    features:
+    - 'Add support for showing flavor access list by using ``flavor show`` command.
+
+      [Bug `1575461 <https://bugs.launchpad.net/bugs/1575461>`_]
+
+      '
+  releasenotes/notes/bug-1575461-4d7d90e792132064.yaml:
+    features:
+    - 'Add ``--project`` option to ``flavor set`` command to set project access
+
+      to a flavor
+
+      [:lpbug:`1575461`]
+
+      '
+    - 'Add ``--project`` option to ``flavor unset`` command to remove project access
+
+      to a flavor
+
+      [:lpbug:`1575461`]
+
+      '
+  releasenotes/notes/bug-1575478-5a0a923c3a32f96a.yaml:
+    fixes:
+    - Fixed ``flavor show/delete/set/unset`` command to properly find a private flavor
+      by flavor name. [Bug `1575478 <https://bugs.launchpad.net/bugs/1575478>`_]
+  releasenotes/notes/bug-1575624-87957ff60ad661a6.yaml:
+    fixes:
+    - Fixed ``flavor set/unset`` command to properly find a flavor to be set/unset
+      by flavor id. [Bug `1575624 <https://bugs.launchpad.net/bugs/1575624>`_]
+  releasenotes/notes/bug-1578819-d1efccfefb18356d.yaml:
+    features:
+    - 'Add ``--internal``, ``--name``, ``--project`` and ``--project-domain``,
+
+      ``--enable`` and ``--disable``, ``--share`` and ``--no share``, ``--status``
+
+      options to the ``network list`` command.
+
+      [Bug `1578819 <https://bugs.launchpad.net/bugs/1578819>`_]
+
+      '
+  releasenotes/notes/bug-1581179-4d15dc504777f9e7.yaml:
+    features:
+    - Add the ``--ip-version`` option to the ``subnet list`` command. This will output
+      subnets based on IP version filter. [`Bug 1581179 <https://bugs.launchpad.net/python-openstackclient/+bug/1581179>`_]
+  releasenotes/notes/bug-1582774-3bba709ef61e33b7.yaml:
+    fixes:
+    - Fix setting defaults for some scope parameters, that were putting invalid scope
+      parameters for some auth plugins. [Bug `1582774 <https://bugs.launchpad.net/bugs/1582774>`_]
+  releasenotes/notes/bug-1582968-4d44912a033b242c.yaml:
+    features:
+    - Add ``image unset`` command [:lpbug:`1582968`]
+  releasenotes/notes/bug-1584596-5b3109487b451bec.yaml:
+    features:
+    - 'Add command ``openstack project purge`` to clean a project''s resources.
+
+      [Bug `1584596 <https://bugs.launchpad.net/bugs/1584596>`_]
+
+      '
+  releasenotes/notes/bug-1588171-61214d0ea482988c.yaml:
+    fixes:
+    - 'Update novaclient ``DEFAULT_API_VERSION`` from 2.0 to 2.1
+
+      [Bug `1588171 <https://bugs.launchpad.net/bugs/1588171>`_]
+
+      '
+  releasenotes/notes/bug-1588384-eb6976fcfb90cb4c.yaml:
+    fixes:
+    - Fix the ``--enable`` option on all commands by changing the ``--enable-beta-commands``
+      global option to ``--os-beta-command``. There are no upgrade impacts for the
+      global option rename since the old name isn't used. [Bug `1588384 <https://bugs.launchpad.net/python-openstackclient/+bug/1588384>`_]
+  releasenotes/notes/bug-1588588-39927ef06ca35730.yaml:
+    upgrade:
+    - All ``set`` and ``unset`` commands now return normally when nothing specified
+      to modify. This will become the default behavior of OSC ``set`` and ``unset``
+      commands. [Bug `1588588 <https://bugs.launchpad.net/python-openstackclient/+bug/1588588>`_]
+  releasenotes/notes/bug-1589332-2941f5286df7e5d4.yaml:
+    features:
+    - 'Add ``--purge`` option to ``volume delete`` command (Volume v2 only) in
+
+      order to removing any snapshots along with volume automatically when user
+
+      delete the volume.
+
+      [Bug `1589332 <https://bugs.launchpad.net/python-openstackclient/+bug/1589332>`_]
+
+      '
+  releasenotes/notes/bug-1589348-4a612a4efc7ed0e5.yaml:
+    features:
+    - Add options ``--up`` and ``--down`` for compute v2 ``compute service set`` command
+      to support force up/down compute service. [Bug `1589348 <https://bugs.launchpad.net/python-openstackclient/+bug/1589348>`_]
+  releasenotes/notes/bug-1589935-8a56e6a18d836db9.yaml:
+    fixes:
+    - Raise ``ArgumentTypeError`` if the input arguments do not match the type ``key=value``
+      when we set properties. [Bug `1589935 <https://bugs.launchpad.net/bugs/1589935>`_]
+  releasenotes/notes/bug-1592062-e327a31a5ae66809.yaml:
+    fixes:
+    - Scope options are now validated after authentication occurs, and only if the
+      user does not have a default project scope. [Bug `1592062 <https://bugs.launchpad.net/bugs/1592062>`_]
+  releasenotes/notes/bug-1592368-a4af69f163a1e208.yaml:
+    fixes:
+    - Fix for network OS_ENDPOINT_TYPE/--os-interface. Previously these were being
+      ignored for network commands which resulted in the public endpoint always being
+      used. [Bug `1592368 <https://bugs.launchpad.net/bugs/1592368>`_]
+  releasenotes/notes/bug-1592761-f45998453d6801f7.yaml:
+    fixes:
+    - Add default IP version in ``ip availability list`` command and make this command
+      work properly without ``--ip-version`` option. [Bug `1592761 <https://bugs.launchpad.net/bugs/1592761>`_]
+  releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml:
+    features:
+    - Support bulk deletion for ``ec2 credentials delete``, ``endpoint delete``, ``service
+      delete`` in identity V2.0 . [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]
+  releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml:
+    features:
+    - 'Support bulk deletion for identity v3 commands: ``consumer``,
+
+      ``credential``, ``domain``, ``ec2creds``, ``endpoint``,
+
+      ``federation_protocol``, ``identity_provider``, ``mapping``,
+
+      ``policy``, ``region``, ``service_provider`` and ``service``.
+
+      [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]
+
+      '
+  releasenotes/notes/bug-1592906-e69b37377278d9c2.yaml:
+    features:
+    - Support bulk deletion for ``volume type delete``. [Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]
+  releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml:
+    features:
+    - 'Add ``--force`` option to ``backup create`` command to allow users to
+
+      back up an in-use volume.
+
+      [Bug `1596443 <https://bugs.launchpad.net/bugs/1596443>`_]
+
+      '
+  releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml:
+    features:
+    - Add ``--property`` option to ``flavor create`` command. [Bug `1596798 <https://bugs.launchpad.net/bugs/1596798>`_]
+  releasenotes/notes/bug-1596818-d4cd93dd4d38d3d6.yaml:
+    features:
+    - 'Add ``--sort`` support to ``project list`` by sorting items in client side
+
+      By default project list will be sorted by name.
+
+      [Bug `1596818 <https://bugs.launchpad.net/bugs/1596818>`_]'
+  releasenotes/notes/bug-1596821-a07599eb4beb6342.yaml:
+    features:
+    - 'Add ``--force`` option to ``volume qos delete`` command to allow users to
+
+      delete in-use QoS specification(s).
+
+      [Bug `1596821 <https://bugs.launchpad.net/bugs/1596821>`_]
+
+      '
+  releasenotes/notes/bug-1597184-f4fb687b3d4d99d9.yaml:
+    features:
+    - 'Add ``--snapshot`` option to ``backup create`` command.
+
+      [Bug `1597184 <https://bugs.launchpad.net/bugs/1597184>`_]
+
+      '
+  releasenotes/notes/bug-1597188-a2ff62b809865365.yaml:
+    features:
+    - 'Add ``--force`` option to ``backup delete`` command to allow delete
+
+      in state other than error or available.
+
+      [Bug `1597188 <https://bugs.launchpad.net/bugs/1597188>`_]
+
+      '
+  releasenotes/notes/bug-1597189-02a8d8a402725860.yaml:
+    features:
+    - 'The ``volume`` argument of the ``volume backup restore`` command is now
+
+      optional and can refer to the name of a new volume that should be created
+
+      rather than a name or ID of an existing volume (which would be
+
+      overwritten). If not provided, cinder will generate a new volume with a
+
+      unique name. To restore a backup to an existing volume, you must now
+
+      specify the ``--force`` option (volume v2, v3 only).
+
+      [Bug `1597189 <https://bugs.launchpad.net/bugs/1597189>`_]
+
+      '
+  releasenotes/notes/bug-1597192-52801f7520287309.yaml:
+    features:
+    - Add ``--property`` option to ``snapshot create`` command. [Bug `1597192 <https://bugs.launchpad.net/bugs/1597192>`_]
+  releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml:
+    features:
+    - 'Add ``--force`` option to ``volume snapshot delete`` command to allow delete
+
+      in state other than error or available.
+
+      [Bug `1597195 <https://bugs.launchpad.net/bugs/1597195>`_]
+
+      '
+  releasenotes/notes/bug-1597198-e36b55f3fd185a3a.yaml:
+    features:
+    - 'Add ``--public`` and ``--private`` options to ``volume type list`` command.
+
+      [Bug `1597198 <https://bugs.launchpad.net/bugs/1597198>`_]
+
+      '
+  releasenotes/notes/bug-1597296-9735f33eacf5552e.yaml:
+    fixes:
+    - Fixed service name lookup in Identity commands to properly handle multiple matches.
+      [Bug `1597296 <https://bugs.launchpad.net/python-openstackclient/+bug/1597296>`_]
+  releasenotes/notes/bug-1600196-6a733dd4e3371df7.yaml:
+    features:
+    - 'Add ``--incremental`` option to ``backup create`` command to allow users to
+
+      create incremental backups.
+
+      [Bug `1600196 <https://bugs.launchpad.net/python-openstackclient/+bug/1600196>`_]
+
+      '
+  releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml:
+    features:
+    - Add ``--project`` and ``--project-domain`` options to ``volume type create``
+      command. [Bug `1602169 <https://bugs.launchpad.net/bugs/1602169>`_]
+  releasenotes/notes/bug-1605088-fea9347336764469.yaml:
+    features:
+    - Support to get server ``rdp``, ``serial``, ``mks`` type console url. [Bug `1605088
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1605088>`_]
+  releasenotes/notes/bug-1605475-84e649fb8c675737.yaml:
+    features:
+    - 'Add ``--limit`` and ``--marker`` options to ``snapshot list`` command.
+
+      [Bug `1605475 <https://bugs.launchpad.net/bugs/1605475>`_]
+
+      '
+  releasenotes/notes/bug-1605774-28aec51f6ec4926e.yaml:
+    features:
+    - Deprecate ``role list`` arguments in favor of ``role assignment`` command. [Bug
+      `1605774 <https://bugs.launchpad.net/python-openstackclient/+bug/1605774>`_]
+  releasenotes/notes/bug-1606105-ca06b230e22ab5c6.yaml:
+    features:
+    - Add support for domain specific roles in ``role`` and``role assignment`` commands.
+      [Bug `1606105 <https://bugs.launchpad.net/python-openstackclient/+bug/1606105>`_]
+  releasenotes/notes/bug-1607959-a52aa93e3793f28a.yaml:
+    fixes:
+    - 'A warning message will be shown when an empty password is used
+
+      for ``user create`` and ``user set`` operations.
+
+      [Bug `1607959 <https://bugs.launchpad.net/bugs/1607959>`_]'
+  releasenotes/notes/bug-1607972-a910a9fbdb81da57.yaml:
+    features:
+    - Add ``--name`` option to command ``object create`` for uploading a file and
+      renaming it. [Bug `1607972 <https://bugs.launchpad.net/bugs/1607972>`_]
+  releasenotes/notes/bug-1609233-90b2ddf8d941050e.yaml:
+    fixes:
+    - 'Fix the ``--class`` option in ``quota set`` and ``quota show``
+
+      commands to not perform a project lookup in Identity.
+
+      [Bug `1609233 <https://bugs.launchpad.net/bugs/1609233>`_]
+
+      '
+  releasenotes/notes/bug-1609767-0602edc4408c2dc6.yaml:
+    features:
+    - Support to update ``per_volume_gigabytes``, ``backup_gigabytes`` and ``backups``
+      quota in ``quota set`` command. [Bug `1609767 <https://bugs.launchpad.net/python-openstackclient/+bug/1609767>`_]
+  releasenotes/notes/bug-1610161-7c34c7b735701bd4.yaml:
+    features:
+    - 'Add ``--ha`` option to ``router create`` command.
+
+      [Bug `1610161 <https://bugs.launchpad.net/bugs/1610161>`_]'
+  releasenotes/notes/bug-1610883-38929f6fc2eefc9a.yaml:
+    features:
+    - 'Add ``--project``, ``--project-domain``, ``--network``, ``--gateway``,
+
+      ``--name`` and ``--subnet-range`` options to the ``subnet list``  command.
+
+      [Bug `1610883 <https://bugs.launchpad.net/bugs/1610883>`_]
+
+      '
+  releasenotes/notes/bug-1610883-e6345c32a35cc290.yaml:
+    features:
+    - 'Make ``subnet list`` command supports listing up subnets with
+
+      dhcp enabled/disabled by adding ``--dhcp`` and ``--no-dhcp``
+
+      options to the command.
+
+      [Bug `1610883 <https://bugs.launchpad.net/bugs/1610883>`_]
+
+      '
+  releasenotes/notes/bug-1612136-051b5f94796e3b51.yaml:
+    features:
+    - 'Add ``--security-group`` and ``--no-security-group`` options to
+
+      ``port create``, ``port set`` and ``port unset`` commands.
+
+      [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+      '
+  releasenotes/notes/bug-1612136-6111b944569b9351.yaml:
+    features:
+    - 'Add ``--allowed-address`` option to ``port create``, ``port set`` and
+
+      ``port unset`` commands. Also add ``--no-allowed-address`` option to
+
+      ``port create`` and ``port set`` commands.
+
+      [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+      '
+  releasenotes/notes/bug-1612136-63aac6377209db38.yaml:
+    features:
+    - 'Add ``--dns-name`` option to ``os port create`` and ``os port set`` commands.
+
+      [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+      '
+  releasenotes/notes/bug-1612136-ec240349a933db12.yaml:
+    features:
+    - 'Add ``--qos-policy`` option to ``port create``,  ``port set`` and
+
+      ``port unset`` commands.
+
+      [Bug `1612136 <https://bugs.launchpad.net/python-openstackclient/+bug/1612136>`_]
+
+      '
+  releasenotes/notes/bug-1612484-e8605ad8966a455e.yaml:
+    features:
+    - 'Add ``--limit`` option to ``volume list`` command in volume v1,
+
+      add ``--limit`` and ``--marker`` options to ``volume list``
+
+      command in volume v2.
+
+      [Bug `1612484 <https://bugs.launchpad.net/bugs/1612484>`_]
+
+      '
+  releasenotes/notes/bug-1612898-bea3b68251d12d81.yaml:
+    features:
+    - 'Add ``--network`` and ``--port`` options to ``server create`` command
+
+      as alternatives to ``--nic`` option.
+
+      [Bug `1612898 <https://bugs.launchpad.net/bugs/1612898>`_]
+
+      '
+  releasenotes/notes/bug-1613231-386b2b1373662052.yaml:
+    features:
+    - 'Add ``--project`` and ``--project-domain`` options to the ``router list``,
+
+      ``floating ip create`` and ``security group list`` commands.
+
+      [Bug `1613231 <https://bugs.launchpad.net/bugs/1613231>`_]
+
+      [Bug `1613629 <https://bugs.launchpad.net/bugs/1613629>`_]
+
+      [Bug `1610909 <https://bugs.launchpad.net/bugs/1610909>`_]
+
+      '
+  releasenotes/notes/bug-1613261-290a64080fead6c0.yaml:
+    features:
+    - Add ``volume backup set`` commands in volume v2. [Bug `1613261 <https://bugs.launchpad.net/python-openstackclient/+bug/1613261>`_]
+  releasenotes/notes/bug-1613533-93279179c6f70117.yaml:
+    features:
+    - 'Add ``--ingress``, ``--egress`` and ``--protocol`` options to
+
+      ``security group rule list`` command.
+
+      [Bug `1613533 <https://bugs.launchpad.net/bugs/1613533>`_]
+
+      '
+  releasenotes/notes/bug-1613597-b1545148b0755e6f.yaml:
+    features:
+    - Add ``volume service set`` commands in volume v1 and v2. [Bug `1613597 <https://bugs.launchpad.net/python-openstackclient/+bug/1613597>`_]
+  releasenotes/notes/bug-1613926-2d0e405831c0b5a9.yaml:
+    features:
+    - 'Add ``--share``, ``--no-share``, ``--project``, ``--project-domain``,
+
+      ``--default``, ``--no-default``, ``--name`` and ``--address-scope``
+
+      options to the ``subnet pool list`` command.
+
+      [Bug `1613926 <https://bugs.launchpad.net/bugs/1613926>`_]
+
+      '
+  releasenotes/notes/bug-1613964-837196399be16b3d.yaml:
+    features:
+    - Add ``consistency group create`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+    - Add ``consistency group delete`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+    - Add ``consistency group show`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+  releasenotes/notes/bug-1613964-86e0afe0e012a758.yaml:
+    features:
+    - Add ``consistency group set`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+  releasenotes/notes/bug-1613964-b3e8d9d828a3822c.yaml:
+    features:
+    - Add ``consistency group add volume`` and ``consistency group remove volume``
+      commands in volume v2. [Bug `1642238 <https://bugs.launchpad.net/python-openstackclient/+bug/1642238>`_]
+  releasenotes/notes/bug-1613964-e5760f4825f1e043.yaml:
+    features:
+    - Add ``consistency group list`` command in volume v2. [Bug `1613964 <https://bugs.launchpad.net/python-openstackclient/+bug/1613964>`_]
+  releasenotes/notes/bug-1613995-10bb3895d702c063.yaml:
+    features:
+    - 'Add a new column ``status`` and ``--long`` option to the result of the
+
+      ``os port list`` command.
+
+      [Bug `1613995 <https://bugs.launchpad.net/bugs/1613995>`_]
+
+      [Bug `1614321 <https://bugs.launchpad.net/bugs/1614321>`_]
+
+      '
+  releasenotes/notes/bug-1614121-a3c5b6892074d5ae.yaml:
+    features:
+    - 'Added ``--egress`` and ``--ingress`` options to
+
+      ``network qos rule create`` and ``network qos rule set`` commands.
+
+      This adds directionality to Network QoS ``bandwidth-limit`` rule type.
+
+      [Bug `1614121 <https://bugs.launchpad.net/python-openstackclient/+bug/1614121>`_]
+
+      '
+  releasenotes/notes/bug-1614379-d8e2815804d53cef.yaml:
+    features:
+    - 'Add ``--long``, ``--status``, ``--project``, ``--project-domain``,
+
+      and ``--router`` options to ``floating ip list`` command.
+
+      [Bug `1614379 <https://bugs.launchpad.net/bugs/1614379>`_]'
+  releasenotes/notes/bug-1614379-da92ded6d19f5ad5.yaml:
+    features:
+    - 'Add ``--port``, ``--fixed-ip-address``, ``--network``,
+
+      options to ``floating ip list`` command
+
+      [Bug `1614379 <https://bugs.launchpad.net/bugs/1614379>`_]'
+  releasenotes/notes/bug-1614385-460b5034ba372463.yaml:
+    features:
+    - Support listing the specified server's ports by new option ``--server`` of ``port
+      list`` command. [Bug `1614385 <https://bugs.launchpad.net/python-openstackclient/+bug/1614385>`_]
+  releasenotes/notes/bug-1614458-c42be5738f447db8.yaml:
+    features:
+    - 'Adds ``--description`` option to ``subnet create`` and
+
+      ``subnet set`` commands.
+
+      [Bug `1614458 <https://bugs.launchpad.net/bugs/1614458>`_]
+
+      '
+  releasenotes/notes/bug-1614823-e89080342f25f2c0.yaml:
+    features:
+    - 'Adds ``--description`` option to ``subnet pool create``
+
+      and ``subnet pool set`` commands.
+
+      [Bug `1614823 <https://bugs.launchpad.net/bugs/1614823>`_]
+
+      '
+  releasenotes/notes/bug-1617384-55c88207115e2a5b.yaml:
+    fixes:
+    - 'Fix prompting for password issue introduced in release 3.0.0
+
+      [Bug `1617384 <https://bugs.launchpad.net/bugs/1617384>`_]
+
+      '
+  releasenotes/notes/bug-1618676-04ff0f335b670567.yaml:
+    features:
+    - Add ``--remote-source`` option to ``volume snapshot create`` command to support
+      creating volume snapshot from an existing remote volume snapshot in volume v2.
+      [Bug `1618676 <https://bugs.launchpad.net/python-openstackclient/+bug/1618676>`_]
+  releasenotes/notes/bug-1619274-e78afd7c12ea2c3d.yaml:
+    fixes:
+    - Skip password prompt when running commands that do not require auth and user
+      auth values are present except for password. [Bug `1619274 <https://bugs.launchpad.net/python-openstackclient/+bug/1619274>`_]
+      *Fixed in release 3.3.0*
+  releasenotes/notes/bug-1620922-7f27942dc00f7108.yaml:
+    fixes:
+    - Do not show ``os-volume-type-access:is_public`` property which is the same as
+      ``is_public`` property of volume type object. [Bug `1620922 <https://bugs.launchpad.net/python-openstackclient/+bug/1620922>`_]
+  releasenotes/notes/bug-1622565-2e715aff8b054401.yaml:
+    fixes:
+    - 'Fix ``--long`` option in ``router list`` command for deployments without
+
+      the ``router_availability_zone`` extension is not enabled.
+
+      [Bug `1622565 <https://bugs.launchpad.net/bugs/1622565>`_]
+
+      '
+  releasenotes/notes/bug-1624085-7cf296649277f405.yaml:
+    fixes:
+    - Fix missing ``_username`` attribute error in ``server ssh`` command. [Bug `1624085
+      <https://bugs.launchpad.net/python-openstackclient/+bug/1624085>`_]
+  releasenotes/notes/bug-1627555-3b47eba215e35b3c.yaml:
+    features:
+    - 'The ``project list`` command lists all projects when called by an
+
+      admin user.  For non-admin users it will now list projects for the
+
+      authenticated user instead of exiting with an authorization failure.
+
+      The ``--my-projects`` option has also been added to the ``project list``
+
+      command to allow admin users to list their own projects.
+
+      [Bug `1627555 <https://bugs.launchpad.net/bugs/1627555>`_]
+
+      '
+  releasenotes/notes/bug-1627913-2adf4182977e5926.yaml:
+    features:
+    - 'Add ``--source-replicated``, ``--consistency-group``, ``--hint`` and
+
+      ``--multi-attach`` options to ``volume create`` command in volume v2.
+
+      Make ``--size`` optional when ``--snapshot``, ``--source`` or
+
+      ``source-replicated`` options are present.
+
+      [Bug `1627913 <https://bugs.launchpad.net/python-openstackclient/+bug/1627913>`_]
+
+      '
+  releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml:
+    security:
+    - 'Mask passwords when ``--debug`` or ``-vv`` options are used.
+
+      [Bug `1630822 <https://bugs.launchpad.net/python-openstackclient/+bug/1630822>`_]
+
+      '
+  releasenotes/notes/bug-1631471-beb0a1c9b4a932cb.yaml:
+    fixes:
+    - 'Fix ``router unset --route`` to correctly removed routes.
+
+      [Bug `1631471 <https://bugs.launchpad.net/bugs/1631471>`_]
+
+      '
+  releasenotes/notes/bug-1633582-df2bee534c2da7fc.yaml:
+    deprecations:
+    - '``volume transfer request accept`` has been changed to move the ``auth-key``
+
+      positional argument to a requried option ``--auth-key``.  This leaves
+
+      the transfer request ID as the only positional arguemnt, as per the
+
+      OpenStackClient command format.  The old format is still functional, but is
+
+      deprecated and will be removed in the next major release.
+
+      '
+    fixes:
+    - 'Fix ``volume transfer request accept`` to not fail the transfer request
+
+      name/ID lookup for non-admin users as the Volume API does not allow non-admin
+
+      users access to transfers in other projects.
+
+      [Bug `1633582 <https://bugs.launchpad.net/python-openstackclient/+bug/1633582>`_]
+
+      '
+    - 'Change the output column order in ``volume transfer request list`` to have
+
+      ``ID`` followed by ``Name`` then the remaining columns.
+
+      '
+  releasenotes/notes/bug-1634333-a2b04d33ca39440e.yaml:
+    features:
+    - 'Add support to allow filtering ports via ``--mac-address``
+
+      option to the ``port list`` command.
+
+      [Bug `1634333 <https://bugs.launchpad.net/bugs/1634333>`_]
+
+      '
+  releasenotes/notes/bug-1634672-7ce577f3adc34eed.yaml:
+    fixes:
+    - 'Fix ``--no-allocation-pool`` option for ``subnet set`` command to
+
+      send the correct value to the Network API.
+
+      [Bug `1518059 <https://bugs.launchpad.net/bugs/1518059>`_]:
+
+      '
+  releasenotes/notes/bug-1634799-1322227c9b0188ca.yaml:
+    features:
+    - 'Add ``--fixed-ip`` option to the ``port list`` command.
+
+      [Bug `1634799 <https://bugs.launchpad.net/bugs/1634799>`_]
+
+      '
+  releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml:
+    features:
+    - 'Add ``--provider-network-type``, ``--provider-physical-network``,  and
+
+      ``--provider-segment`` options to the ``network list`` command.
+
+      [Bug `1635580 <https://bugs.launchpad.net/bugs/1635580>`_]
+
+      '
+  releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml:
+    features:
+    - 'Add ``--name``, ``--ip-version``, ``--project``, ``--project-domain``,
+
+      ``--share``, ``--no-share`` options to the ``address scope list`` command.
+
+      [Bug `1636046 <https://bugs.launchpad.net/bugs/1636046>`_]
+
+      '
+  releasenotes/notes/bug-1637074-1b0e409f30f715ca.yaml:
+    features:
+    - 'Add ``--long`` option and more columns to the ``hypervisor list`` command.
+
+      [Bug `1637074 <https://bugs.launchpad.net/bugs/1637074>`_]
+
+      '
+  releasenotes/notes/bug-1637365-b90cdcc05ffc7d3a.yaml:
+    upgrade:
+    - 'Rename the ``--src-group`` and ``--src-ip`` options in the
+
+      ``security group rule create`` command to ``--remote-group``
+
+      and ``--remote-ip``.
+
+      The ``--src-group`` and ``--src-ip`` options are deprecated but still
+
+      supported, and will be removed in a future release.
+
+      [Bug `1637365 <https://bugs.launchpad.net/python-openstackclient/+bug/1637365>`_]
+
+      '
+  releasenotes/notes/bug-1637945-f361c834381d409c.yaml:
+    features:
+    - 'Add ``--name``, ``--enable``, ``--disable`` options to
+
+      ``router list`` command.
+
+      [Bug `1637945 <https://bugs.launchpad.net/bugs/1637945>`_]
+
+      '
+  releasenotes/notes/bug-1639231-21823768bd54170a.yaml:
+    features:
+    - 'The  ``image list`` command will now sort by name in ascending order by
+
+      default. ``--sort`` option will have the default value of ``name:asc``.
+
+      [Bug `1639231 <https://bugs.launchpad.net/bugs/1639231>`_]
+
+      '
+  releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml:
+    features:
+    - 'Add ``--name``, ``--status``, ``--volume``, ``--marker`` and ``--limit`` options
+
+      to ``volume backup list`` command
+
+      [Bug `1639712 <https://bugs.launchpad.net/bugs/1639712>`_]
+
+      '
+  releasenotes/notes/bug-1640086-21d7e5f2ce18f53c.yaml:
+    features:
+    - 'Add ``--human-readable`` option to ``image show`` to display
+
+      image size in human readable format (such as K, M, G, T,..)
+
+      [Bug `1640086 <https://bugs.launchpad.net/bugs/1640086>`_]
+
+      '
+  releasenotes/notes/bug-1641868-97c284e33f944c2d.yaml:
+    features:
+    - 'Add filters ``--agent-type`` and ``--host``
+
+      to ``network agent list`` command
+
+      [Bug `1641868 <https://bugs.launchpad.net/bugs/1641868>`_]
+
+      '
+  releasenotes/notes/bug-1642030-166b2b28c8adf22e.yaml:
+    features:
+    - 'Add ``server event list`` and ``server event show`` commands.
+
+
+      A server event is the event record of actions performed on a server,
+
+      including: event type(create, delete, reboot and so on),
+
+      event result(success, error), start time, finish time and others.
+
+      [Bug `1642030 <https://bugs.launchpad.net/python-openstackclient/+bug/1642030>`_]
+
+      '
+  releasenotes/notes/bug-1642238-3032c7fe7f0ce29d.yaml:
+    features:
+    - Add ``consistency group snapshot create``, ``consistency group snapshot delete``,
+      ``consistency group snapshot list`` and ``consistency group snapshot show``
+      commands in volume v2. [Bug `1642238 <https://bugs.launchpad.net/python-openstackclient/+bug/1642238>`_]
+  releasenotes/notes/bug-1642301-18b08e0cd4b11687.yaml:
+    fixes:
+    - 'Fix ``TypeError: __init__() got an unexpected keyword argument ''project_domain_id''``
+
+      error with non-password authentication types.
+
+      [Bug `1642301 <https://bugs.launchpad.net/bugs/1642301>`_]'
+  releasenotes/notes/bug-1642301-ad04424c80e8fe50.yaml:
+    fixes:
+    - Fix problem with ``--os-auth-type token_endpoint`` that caused exceptions when
+      recent os-client-config version 1.23.0 or newer is installed. [Bug `1642301
+      <https://bugs.launchpad.net/bugs/1642301>`_] *Fixed in release 3.4.1*
+  releasenotes/notes/bug-1642772-19f53765bef8ee91.yaml:
+    fixes:
+    - Changed the default version of ``OS_IMAGE_API_VERSION`` to ``2``. Image v1 has
+      been deprecated for more than six months and other projects, such as `shade`
+      and `os-client-config` are using Image v2 by default as well. [Bug `1642772
+      <https://bugs.launchpad.net/bugs/1642772>`_]
+  releasenotes/notes/bug-1643861-b17ad5dfcb4304ff.yaml:
+    features:
+    - Add ``Is Public`` column to ``volume type list``. [Bug `1643861 <https://bugs.launchpad.net/python-openstackclient/+bug/1643861>`_]
+  releasenotes/notes/bug-1645252-219bfd50c8f04846.yaml:
+    features:
+    - 'Add ``--name``, ``--status`` and ``--volume`` options
+
+      to ``volume snapshot list`` command
+
+      [Bug `1645252 <https://bugs.launchpad.net/bugs/1645252>`_]
+
+      '
+  releasenotes/notes/bug-1647242-fdc39e564372857b.yaml:
+    features:
+    - 'Add ``--deleted`` and ``--changes-since`` options to ``server list``
+
+      command.
+
+      [Bug `1647242 <https://bugs.launchpad.net/bugs/1647272>`_]
+
+      '
+  releasenotes/notes/bug-1647406-c936581034a1b6e4.yaml:
+    fixes:
+    - "Allow ``--block-device-mapping`` option to work correctly with\n``--volume``\
+      \ option in ``server create`` command.\nAfter :lpbug:`1383338` ``--block-device-mapping``\
+      \ was ignored if\n``--volume`` was present. Block device mappings are now appended\n\
+      to the mapping created by the ``--volume`` option if it is present.\nThe device\
+      \ name of the boot volume specificed in the ``--volume`` option\nis no longer\
+      \ assumed to be *'vda'* but now uses the hypervisor's boot\nindex to obtain\
+      \ the device name.  This maintains the status quo for\n**QEMU/KVM** hypervisors\
+      \ but **XEN**, **parallels** and others \n*virt types* that have device naming\
+      \ is different from ``vd*``\nshould now also work correctly.\n[:lpbug:`1497845`]\n\
+      [:lpbug:`1647406`]\n"
+  releasenotes/notes/bug-1648087-21dfb7250abfdbe9.yaml:
+    features:
+    - 'Add ``--project`` and ``--project-domain`` filtering options
+
+      to ``port list`` command.
+
+      [Bug `1648087 <https://bugs.launchpad.net/bugs/1648087>`_]
+
+      '
+  releasenotes/notes/bug-1648307-a2c6d7698e927449.yaml:
+    features:
+    - 'Add ``--type``, ``--action``, ``--long`` options
+
+      to ``network rbac list`` command
+
+      [Bug `1648307 <https://bugs.launchpad.net/bugs/1648307>`_]
+
+      '
+  releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml:
+    fixes:
+    - 'Fixed a ``__init__() got an unexpected keyword argument ''project_name''``
+
+      error in various networking commands when ``help`` or ``--help`` was used.
+
+      [Bug `1650026 <https://bugs.launchpad.net/bugs/1650026>`_]
+
+      '
+  releasenotes/notes/bug-1650342-22cb88ef37a41872.yaml:
+    features:
+    - Add ``ploop`` as a valid disk format choice for ``image create`` and ``image
+      set`` commands. [Bug `1650342 <https://bugs.launchpad.net/bugs/1650342>`_]
+  releasenotes/notes/bug-1651117-a1df37e7ea939ba4.yaml:
+    features:
+    - 'Add ``--encryption-provider``, ``--encryption-cipher``, ``--encryption-key-size``
+
+      and ``--encryption-control-location`` options to ``volume type set`` and
+
+      ``volume type create`` commands.
+
+      Add ``--encryption-type`` option to ``volume type unset``, ``volume type list``
+
+      and ``volume type show`` commands.
+
+      [Bug `1651117 <https://bugs.launchpad.net/bugs/1651117>`_]
+
+      '
+  releasenotes/notes/bug-1652827-f59bbd1b64df958d.yaml:
+    fixes:
+    - 'Fix an endpoint version problem with Image endpoints that contained the
+
+      substring ''v2''.
+
+      [Bug `1652827 <https://bugs.launchpad.net/bugs/1652827>`_]
+
+      '
+  releasenotes/notes/bug-1654221-a564ab75a6afc332.yaml:
+    fixes:
+    - 'Fix ``--project`` option for ``flavor create`` command when the
+
+      ID for the new flavor is auto generated.
+
+      [Bug `1654221 <https://bugs.launchpad.net/bugs/1654221>`_]
+
+      '
+  releasenotes/notes/bug-1655445-96c787e3a51226e0.yaml:
+    fixes:
+    - 'Work around a bug in OpenStackSDK 0.9.11 and 0.9.12 that causes
+
+      ``quota set --network`` to fail.
+
+      [Bug `1655445 <https://bugs.launchpad.net/python-openstackclient/+bug/1655445>`_]
+
+      '
+  releasenotes/notes/bug-1655537-20b0eb676afa278f.yaml:
+    fixes:
+    - 'Fixed a ``''Quota'' object is not iterable`` error in the ``quota show`` command
+
+      that appeared with the initial release of openstacksdk v0.9.11 and v0.9.12.
+
+      [Bug `1655537 <https://bugs.launchpad.net/bugs/1655537>`_]
+
+      '
+  releasenotes/notes/bug-1656402-88b12760fb2d4ef9.yaml:
+    fixes:
+    - 'Fix ``floating ip delete`` and ``floating ip show`` to accept IP addresses
+
+      in addition to IDs to select floating IPs to delete or show.
+
+      [Bug `1656402 <https://bugs.launchpad.net/bugs/1656402>`_
+
+      '
+  releasenotes/notes/bug-1656572-b40303ae50a41000.yaml:
+    fixes:
+    - 'Work around a bug in OpenStackSDK 0.9.11 and 0.9.12 that causes
+
+      ``quota show --default`` to fail.
+
+      [Bug `1656572 <https://bugs.launchpad.net/python-openstackclient/+bug/1656572>`_]
+
+      '
+  releasenotes/notes/bug-1656767-36a3d4b9fac335c9.yaml:
+    fixes:
+    - 'Fixed a ``volume qos create`` display mistake in argument of ``specs``.
+
+      [Bug `1656767 <https://bugs.launchpad.net/python-openstackclient/+bug/1656767>`_]
+
+      '
+  releasenotes/notes/bug-1656788-2f5bda2205bc0329.yaml:
+    fixes:
+    - 'Fixed the ``port set`` and ``port unset`` command failures
+
+      (AttributeError) when ``--security-group`` option is included.
+
+      [Bug `1656788 <https://bugs.launchpad.net/python-openstackclient/+bug/1656788>`_]
+
+      '
+  releasenotes/notes/bug-1657956-977a615f01775288.yaml:
+    fixes:
+    - 'Change column name ``Display Name`` to ``Name`` in ``volume list`` output.
+
+      Current ``volume list --name`` command uses ``display_name`` as search_opts
+
+      to send to cinder API, and show the result table with ``Display Name``
+
+      as column title. Replace all ``Display Name`` by ``Name`` to be consistent
+
+      with other list commands.
+
+
+      Support a mapping for volume list -c ``Display Name`` (Volume v1 and v2)
+
+      and volume create/show -c ``display_name`` (Volume v1) to maintain backward
+
+      compatibility until the next major release.
+
+      [Bug `1657956 <https://bugs.launchpad.net/python-openstackclient/+bug/1657956>`_]
+
+      '
+  releasenotes/notes/bug-1658147-9de9ae222f9db9ae.yaml:
+    features:
+    - 'Add ``--domain`` options to the ``user set`` command.
+
+      Allows specification of domain context when changing users.
+
+      [Bug `1658147 <https://bugs.launchpad.net/bugs/1658147>`_]
+
+      '
+  releasenotes/notes/bug-1658189-d2b390ad74c96c79.yaml:
+    fixes:
+    - 'Make the ``role assignment list`` command callable without administrator
+
+      permissions if restricted to the user''s own project with the ``--project``
+      option.
+
+      [Bug `1658189 <https://bugs.launchpad.net/python-openstackclient/+bug/1658189>`_]
+
+      '
+  releasenotes/notes/bug-1658582-80a76f6b0af0ca12.yaml:
+    fixes:
+    - 'Correctly handle non-admin in ``create trust`` command when looking
+
+      up role names.
+
+      [Bug `1658582 <https://bugs.launchpad.net/python-openstackclient/+bug/1658582>`_]
+
+      '
+  releasenotes/notes/bug-1658614-f84a8cece6f2ef8c.yaml:
+    fixes:
+    - 'Fix wrong behavior of parsing plugin service name when the service name end
+
+      with keyword ``os``, like: antiddos. That cause the service api version
+
+      specified by users don''t work.
+
+      [Bug `1658614 <https://bugs.launchpad.net/python-openstackclient/+bug/1658614>`_]
+
+      '
+  releasenotes/notes/bug-1659878-f6a55b7166d99ca8.yaml:
+    fixes:
+    - 'The ``network create`` command was ignoring the ``--project`` option and
+
+      creating networks owned by the current authenticated user''s project.  This
+
+      was a regression introduced in OSC 3.8.0.
+
+      [Bug `1659878 <https://bugs.launchpad.net/bugs/1659878>`_]
+
+      '
+  releasenotes/notes/bug-1659894-4518b10615498ba9.yaml:
+    fixes:
+    - 'Now the positional parameter ``<snapshot-name>`` of ``volume snapshot create``
+
+      command is no longer optional, it should be always present.
+
+      [Bug `1659894 <https://bugs.launchpad.net/bugs/1659894>`_]
+
+      '
+  releasenotes/notes/bug-1659967-644a8ee3621c9e81.yaml:
+    fixes:
+    - '``security group list`` command now can display project IDs in the ``Project``
+      column
+
+      of the command output.
+
+      [Bug `1659967 <https://bugs.launchpad.net/bugs/1659967>`_]
+
+      '
+  releasenotes/notes/bug-1659993-a5fe43bef587e490.yaml:
+    fixes:
+    - 'The ``address scope list`` command failed with ''HttpException: Bad Request''
+
+      when the ``--share`` or ``--no-share`` options were used.
+
+      [Bug `1659993 <https://bugs.launchpad.net/bugs/1659993>`_]
+
+      '
+  releasenotes/notes/bug-1661814-1692e68a1d2d9770.yaml:
+    fixes:
+    - 'Fix ``module list --all`` command failed, and enhance the related unit
+
+      tests and funcational tests.
+
+      [Bug `1661814 <https://bugs.launchpad.net/python-openstackclient/+bug/1661814>`_]
+
+      '
+  releasenotes/notes/bug-1663520-d880bfa51ca7b798.yaml:
+    fixes:
+    - 'Fix ``server create`` command failed when ``--nic`` auto or none.
+
+      ``auto`` and ``none`` options was added into --nic argument of server
+
+      create command, but that don''t work and raise internal error when execute
+
+      command. The patch fix that issue.
+
+      [Bug `1663520 <https://bugs.launchpad.net/python-openstackclient/+bug/1663520>`_]
+
+      '
+  releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml:
+    fixes:
+    - 'Allow users to create centralized (distributed=False)
+
+      routers using the ``--centralized`` option in ``router create``.
+
+      Without this, routers are created based on the default
+
+      neutron configuration of the deployment, which, for example,
+
+      could be ''distributed''.
+
+      [Bug `1664255 <https://bugs.launchpad.net/bugs/1664255>`_]
+
+      '
+  releasenotes/notes/bug-1665231-3df6d090d137fe4f.yaml:
+    fixes:
+    - 'Allow ``--default`` and ``--no-default`` options in  ``network create`` command
+      to
+
+      be recognized when ``--external`` is not present.
+
+      [Bug `1665231 <https://bugs.launchpad.net/python-openstackclient/+bug/1665231>`_]
+
+      '
+  releasenotes/notes/bug-1666780-c10010e9061689d3.yaml:
+    features:
+    - 'Add ``--group`` option to the ``command list`` command to filter the
+
+      commands by group name: ``openstack command list --group volume`` will
+
+      list all Volume commands for the selected API version.  Use
+
+      ``--os-XXXX-api-version`` to select a specific API version for the desired APIs.
+
+
+      This provides an alternative to searching help output to list the comamnds
+
+      available for specific APIs.  Note that the ``--group`` argument is used as
+
+      a simple substring search in the Command Group column.
+
+      [Bug `1666780 <https://bugs.launchpad.net/python-openstackclient/+bug/1666780>`_]
+
+      '
+  releasenotes/notes/bug-1667266-6497727abc2af9a5.yaml:
+    fixes:
+    - 'Clarify the ``--block-device-mapping`` option of the ``server create``
+
+      command: fix ValueError when the ``--block-device-mapping`` option''s
+
+      argument is in the wrong format; support creating a block device from
+
+      a snapshot; add details to the help output about the option format.
+
+      [Bug `1667266 <https://bugs.launchpad.net/python-openstackclient/+bug/1667266>`_]
+
+      '
+  releasenotes/notes/bug-1667294-f92efa49627eb00a.yaml:
+    features:
+    - 'Add ``--default-quota`` option to ``subnet pool create``
+
+      and ``subnet pool set`` commands.
+
+      [Bug `1667294 <https://bugs.launchpad.net/python-openstackclient/+bug/1667294>`_]
+
+      '
+  releasenotes/notes/bug-1667699-6dad786b128ca8b5.yaml:
+    fixes:
+    - 'Fix the ``Ethertype`` column output of ``security group rule list`` command.
+
+      [Bug `1667699 <https://bugs.launchpad.net/python-openstackclient/+bug/1667699>`_]
+
+      '
+  releasenotes/notes/bug-1670707-c4799fbed39ef75b.yaml:
+    fixes:
+    - 'Add ``--mac-address`` option to ``port set`` command.
+
+      [Bug `1670707 <https://launchpad.net/bugs/1670707>`_]
+
+      '
+  releasenotes/notes/bug-1672634-ef754cb5109dd0f2.yaml:
+    fixes:
+    - 'Narrow acceptable negative response codes for ``group contains user``
+
+      [Bug `1672634 <https://bugs.launchpad.net/python-openstackclient/+bug/1672634>`_]
+
+      '
+  releasenotes/notes/bug-1675489-a1d226f2ee911420.yaml:
+    features:
+    - Add router interfaces info (as field ``interfaces_info``) to ``router show``
+      command. The information of router interface include port's ID, IP address,
+      the subnet ID it belongs. [Bug `1675489 <https://bugs.launchpad.net/python-openstackclient/+bug/1675489>`_]
+  releasenotes/notes/bug-1677236-7de9d11c3f0fb5ed.yaml:
+    fixes:
+    - 'Fix creating a server with a block-device-mapping when volume_size
+
+      is empty.
+
+      [Bug `1677236 <https://bugs.launchpad.net/bugs/1652827>`_]
+
+      '
+  releasenotes/notes/bug-1684989-3bda158a822d2f73.yaml:
+    features:
+    - Add ``--data-plane-status`` option to ``port set`` and ``port unset`` commands.
+      [Bug `1684989 <https://bugs.launchpad.net/bugs/1684989>`_]
+  releasenotes/notes/bug-1687814-743ad8418923d5e3.yaml:
+    fixes:
+    - 'Allow the ``--security-group`` option from the ``server create`` command
+
+      to be specified by name or ID.  This also checks that the security group exist
+
+      before creating the server.
+
+      [Bug `1687814 <https://bugs.launchpad.net/python-openstackclient/+bug/1687814>`_]
+
+      '
+  releasenotes/notes/bug-1688194-bb008b65267a1169.yaml:
+    fixes:
+    - 'Fix issue in ``port list`` command when no Compute endpoint is in the
+
+      Service Catalog.
+
+      [Bug `1688194 <https://bugs.launchpad.net/bugs/1688194>`_]
+
+      '
+  releasenotes/notes/bug-1689233-c3f98e159c75374e.yaml:
+    fixes:
+    - 'Raise exact exception when extension don''t exist in ``extension show``
+
+      command, and keep the column display order consist in ``extension list``
+
+      with and without ``--long`` option.
+
+      [Bug `1689233 <https://bugs.launchpad.net/python-openstackclient/+bug/1689233>`_]
+
+      '
+  releasenotes/notes/bug-1696111-e2cf9233fa872eb7.yaml:
+    fixes:
+    - 'Fixed an issue where a trust could not be created if multiple roles had
+
+      the same name. A role''s ID is now sent to the identity service instead.
+
+      [Bug `1696111 <https://bugs.launchpad.net/keystone/+bug/1696111>`_]
+
+      '
+  releasenotes/notes/bug-1698390-0df8f0ec4fe354de.yaml:
+    features:
+    - 'Added the ``--domain`` option to the ``identity provider create`` command to
+
+      associate an existing domain with an identity provider on its creation.
+
+
+      [Bug `1698390 <https://bugs.launchpad.net/python-openstackclient/+bug/1698390>`_]
+
+      '
+  releasenotes/notes/bug-1698742-66d9d4e6c7ad274a.yaml:
+    features:
+    - 'Add ``--name`` and ``--status`` options to ``image list`` command
+
+      to filter images based on name and status respectively.
+
+      [Bug `1698742 <https://bugs.launchpad.net/bugs/1698742>`_]
+
+      '
+  releasenotes/notes/bug-1703278-5e45a92e43552dec.yaml:
+    fixes:
+    - 'Add ``--image`` and ``--password`` options to the ``server rescue`` command.
+
+      [Bug `1703278 <https://bugs.launchpad.net/python-openstackclient/+bug/1703278>`_]
+
+      '
+  releasenotes/notes/bug-1704097-8ff1ce1444b81b04.yaml:
+    fixes:
+    - 'Fix an issue with the ``--domain`` option when used with the ``project show``,
+
+      ``user show`` and ``user set`` commands.  The domain filter did not work when
+
+      the login user''s project name or user name is the same as the requested resource
+
+      name in the specified domain.
+
+      [Bug `1704097 <https://bugs.launchpad.net/python-openstackclient/+bug/1704097>`_]
+
+      '
+  releasenotes/notes/bug-1708570-bb19e1213e887723.yaml:
+    features:
+    - 'Add ``--password`` option to ``server create`` command, allowing users to
+
+      set the admin password when creating a new instance.
+
+      '
+  releasenotes/notes/bug-1711301-17754f487973d4c1.yaml:
+    fixes:
+    - 'Fix occurrences of the ``network agent delete`` command failing with newer
+
+      releases of python-openstacksdk.
+
+      [Bug `1711301 <https://bugs.launchpad.net/python-openstackclient/+bug/1711301>`_]
+
+      '
+  releasenotes/notes/bug-1711301-472b577f074edd43.yaml:
+    fixes:
+    - 'Fix occurrences of the ``network agent delete`` command failing with newer
+
+      releases of python-openstacksdk.
+
+      [Bug `1711301 <https://bugs.launchpad.net/python-openstackclient/+bug/1711301>`_]
+
+      '
+  releasenotes/notes/bug-1711301-633255f813c71d2a.yaml:
+    fixes:
+    - 'Fix occurrences of the ``network agent delete`` command failing with newer
+
+      releases of python-openstacksdk.
+
+      [Bug `1711301 <https://bugs.launchpad.net/python-openstackclient/+bug/1711301>`_]
+
+      '
+  releasenotes/notes/bug-1712242-934bbe2f2378f5bd.yaml:
+    features:
+    - 'Add ``any`` as a ``--protocol`` option to ``security group rule create``
+
+      command.
+
+      [Bug `1517134 <https://bugs.launchpad.net/bugs/1712242>`_]
+
+      '
+    fixes:
+    - 'It is now possible to create a security rule without specifying protocol
+
+      (using ``--protocol any``), which skips sending the protocol to the API
+
+      server entirely. Previously TCP was forced as default protocol when none
+
+      was specified.
+
+      '
+  releasenotes/notes/bug-1714878-46806jv2yv13q054.yaml:
+    features:
+    - 'Add ``--dns-domain`` option to ``port create`` and ``port set`` commands.
+
+      Requires the ``dns_domain for ports`` extension to be enabled. See the
+
+      `Neutron DNS integration <https://docs.openstack.org/neutron/latest/admin/config-dns-int.html>`_
+
+      documentation for information how to use this.
+
+      [Bug `1714878 <https://bugs.launchpad.net/python-openstackclient/+bug/1714878>`_]
+
+      '
+  releasenotes/notes/bug-1716789-abfae897b7e61246.yaml:
+    fixes:
+    - 'Change the default value of ``--protocol`` option to ``any`` in
+
+      ``security group rule create`` command when using the Neutron v2 API.
+
+      [Bug `1716789 <https://bugs.launchpad.net/bugs/1716789>`_]
+
+      '
+    upgrade:
+    - 'Commands that assumed the default value of ``--protocol`` to be ``tcp``
+
+      now must include ``--protocol tcp`` explicitly in Network commands.
+
+      '
+  releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml:
+    fixes:
+    - 'Fix the ``project purge`` command to correctly delete only images owned by
+      the
+
+      specified project ID when run by an administrative user.
+
+      [Bug `1717130 <https://bugs.launchpad.net/python-openstackclient/+bug/1717130>`_]
+
+      '
+  releasenotes/notes/bug-1717829-c1de1d777d3abaf9.yaml:
+    fixes:
+    - 'Add ``--no-fixed-ip`` option to ``port create`` command.
+
+      [Bug `1717829 <https://launchpad.net/bugs/1717829>`_]
+
+      '
+  releasenotes/notes/bug-1719413-0401d05c91cc9094.yaml:
+    fixes:
+    - 'Fix an issue with ``endpoint list`` working slow because it is issuing one
+      GET
+
+      request to /v3/services/<id> Keystone API for each endpoint. In case of HTTPS
+
+      keystone endpoint and multiple regions it can take significant amount of time.
+
+      [Bug `1719413 <https://bugs.launchpad.net/python-openstackclient/+bug/1719413>`_]
+
+      '
+  releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml:
+    fixes:
+    - 'Accept ``0`` as a valid value in the ``image set`` ``--min-disk`` and ``--min-ram``
+      options.
+
+      .. _bug 1719499: https://bugs.launchpad.net/python-openstackclient/+bug/1719499
+
+      '
+  releasenotes/notes/bug-1728525-2c40f0c19adbd0e8.yaml:
+    fixes:
+    - 'Add ``target-all-projects`` option in ``rbac create`` command.
+
+      [Bug `1728525 <https://bugs.launchpad.net/python-openstackclient/+bug/1728525>`_]
+
+      '
+  releasenotes/notes/bug-1731848-71d0a5fdb1a34a8b.yaml:
+    fixes:
+    - 'Remove the type value limit in credentials when do create,
+
+      reset or list. Now ''totp'' method is supported in keystone
+
+      project and we could create credentials with ''totp'' type.
+
+      [Bug `1731848 <https://bugs.launchpad.net/bugs/1731848>`_]
+
+      '
+  releasenotes/notes/bug-1732216-b41bfedebff911e1.yaml:
+    fixes:
+    - 'Fix the operation of the ``--changes-since`` option to the ``server list``
+      command.
+
+      [Bug `1732216 <https://bugs.launchpad.net/python-openstackclient/+bug/1732216>`_]
+
+      '
+  releasenotes/notes/bug-1732938-868963acedaa307e.yaml:
+    fixes:
+    - 'Remove the client-side check for valid ``--policy`` values in the
+
+      ``server group create`` command.  Specify ``--os-compute-api-version 2.15``
+
+      or higher for the ``soft-affinity`` or ``soft-anti-affinity`` policy.
+
+      [Bug `1732938 <https://bugs.launchpad.net/python-openstackclient/+bug/1732938>`_]
+
+      '
+  releasenotes/notes/bug-1732938-e4d91732ef777f9a.yaml:
+    fixes:
+    - 'Remove the client-side check for valid ``--policy`` values in the
+
+      ``server group create`` command.  Specify ``--os-compute-api-version 2.15``
+
+      or higher for the ``soft-affinity`` or ``soft-anti-affinity`` policy.
+
+      [Bug `1732938 <https://bugs.launchpad.net/python-openstackclient/+bug/1732938>`_]
+
+      '
+  releasenotes/notes/bug-1735836-9be6d777a6e6410b.yaml:
+    fixes:
+    - '``openstack subnet create`` failed with a NoneType exception when
+
+      there were no tags.
+
+      [Bug `1735836 <https://bugs.launchpad.net/python-openstackclient/+bug/1735836>`_]
+
+      '
+  releasenotes/notes/bug-1740232-91ad72c2ac165f35.yaml:
+    fixes:
+    - 'Fix RuntimeError in ``project show`` command running under Python 3.
+
+      [Bug `1740232 <https://bugs.launchpad.net/python-openstackclient/+bug/1740232>`_]
+
+      '
+  releasenotes/notes/bug-1741223-7a5c5b6e7f232628.yaml:
+    fixes:
+    - '''NoneType'' object is not iterable when Glance cannot find image data in its
+
+      backend.
+
+      [Bug `1741223 <https://bugs.launchpad.net/ironic/+bug/1741223>`_]
+
+      '
+  releasenotes/notes/bug-1742453-ae4be6de90a3ae1d.yaml:
+    fixes:
+    - 'The ``server list --all`` command now resolves non-public flavor names,
+
+      too, so that the ``Flavor`` column will be properly populated.
+
+      [Bug `1742453 <https://bugs.launchpad.net/bugs/1742453>`_]
+
+      '
+  releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml:
+    features:
+    - 'Add ``--attached`` and ``--detached`` options to ``volume set`` command to
+      set the
+
+      volume status in the database.  This is the functional equivalent to
+
+      ``cinder reset-state --attach-status``.
+
+      [`bug 1745699 <https://bugs.launchpad.net/python-openstackclient/+bug/1745699>`_'
+  releasenotes/notes/bug-1750983-420945d6c0afb509.yaml:
+    features:
+    - 'Add ``--tag`` and ``--no-tag`` options to ``security group create`` and
+
+      ``security group set`` commands.
+
+      [Bug `1750983 <https://bugs.launchpad.net/python-openstackclient/+bug/1750983>`_]
+
+      '
+    - 'Add ``--tags``, ``--any-tags``, ``--not-tags`` and ``--not-any-tags`` options
+
+      to ``security group list`` command.
+
+      [Bug `1750983 <https://bugs.launchpad.net/python-openstackclient/+bug/1750983>`_]
+
+      '
+    - 'Add ``--tag`` and ``--all-tag`` options to ``security group unset`` command.
+
+      [Bug `1750983 <https://bugs.launchpad.net/python-openstackclient/+bug/1750983>`_]
+
+      '
+  releasenotes/notes/bug-1750985-a5345f715a14825c.yaml:
+    fixes:
+    - 'Add ``--tag`` support to ``floating ip create|list|set|unset`` commands.
+
+      [:lpbug:`1750985`]
+
+      '
+  releasenotes/notes/bug-1751104-compute-api-2.47-4bfa21cfaa13f408.yaml:
+    fixes:
+    - 'The ``server show`` command will now properly show the server''s
+
+      flavor information when using ``--os-compute-api-version 2.47`` or higher.
+
+      [Bug `1751104 <https://storyboard.openstack.org/#!/story/1751104>`_]
+
+      '
+  releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml:
+    fixes:
+    - 'Re-open stdout in binary mode before writing object data in
+
+      ``object save --file -`` command.
+
+      [Bug `1775482 <https://bugs.launchpad.net/python-openstackclient/+bug/1775482>`_]
+
+      '
+  releasenotes/notes/bug-1777153-750e6044aa28d5d8.yaml:
+    deprecations:
+    - 'The ``--project`` and ``--user`` options for the ``volume create``
+
+      command have been deprecated. They are deprecated because Cinder''s
+
+      volume create API ignores the corresponding API inputs.
+
+      '
+    fixes:
+    - 'Fix ``volume create`` by removing two broken options. The ``--project``
+
+      and ``--user`` options were intended to specify an alternate project
+
+      and/or user for the volume, but the Volume service''s API does not
+
+      support this behavior. This caused the volume to be created, but
+
+      without the expected project/user values. However, an alternate
+
+      project and/or user may be specified using identity overrides (e.g.
+
+      --os-username, --os-project-id).
+
+      '
+  releasenotes/notes/bug-1784879-9b632174d4af853f.yaml:
+    features:
+    - 'Add ``--dns-publish-fixed-ip`` and ``--no-dns-publish-fixed-ip``
+
+      options to ``create subnet`` and ``set subnet`` commands to
+
+      control the publishing of fixed IPs in DNS when the
+
+      ``subnet_dns_publish_fixed_ip`` Neutron extension is enabled.
+
+      [Bug `1784879 <https://bugs.launchpad.net/neutron/+bug/1784879>`_]
+
+      '
+  releasenotes/notes/bug-1827844-8f1de120087c6a22.yaml:
+    features:
+    - 'Add ``--changes-before`` option to the ``server list`` command.
+
+      This requires Compute API version ''2.66'' or later.
+
+      [:lpbug: `1827844`]
+
+      '
+  releasenotes/notes/bug-1946816-7665858605453578.yaml:
+    fixes:
+    - 'Filtering servers by tags (``server list --tag``,
+
+      ``server list --not-tag``) now works correctly.
+
+      [Bug `1946816 <https://bugs.launchpad.net/bugs/1946816>`_]
+
+      '
+  releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml:
+    fixes:
+    - '[Story `2005246 <https://storyboard.openstack.org/#!/story/2005246>`_]
+
+      The `is_domain` property safely handles type checking.
+
+      '
+  releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml:
+    fixes:
+    - 'Fix ``endpoint group delete`` command to properly delete endpoint groups.
+
+      [Story `2005521 <https://storyboard.openstack.org/#!/story/2005521>`_]'
+  releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml:
+    fixes:
+    - 'You can now remove role assignments from keystone that reference non-existent
+
+      users or groups.
+
+
+      [Bug `2006635 <https://storyboard.openstack.org/#!/story/2006635>`_]
+
+      '
+  releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml:
+    fixes:
+    - 'Fixes the "No server with a name or ID of ''id'' exists" error when running
+
+      ``server list --deleted --marker``. The fix removes using a name for
+
+      the marker when both ``--deleted`` and ``--marker`` are used. In
+
+      this scenario an ID must be supplied for the marker.
+
+      [Story `2006761 <https://storyboard.openstack.org/#!/story/2006761>`_]
+
+      '
+  releasenotes/notes/bug-2007489-42e41b14e42128ce.yaml:
+    features:
+    - 'Add ``server migration abort`` command to abort ongoing live migrations.
+
+      '
+  releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml:
+    features:
+    - Add ``server migration force complete`` command to force complete ongoing live
+      migrations.
+  releasenotes/notes/bug-2010376-e15362bdd6c8d6ec.yaml:
+    fixes:
+    - 'The ``server create`` command will no longer insist on an ``--image``,
+
+      ``--image-property``, ``--volume`` or ``--snapshot`` argument when a
+
+      volume is provided with a boot index of ``0`` via the ``--block-device``
+
+      option.
+
+      '
+  releasenotes/notes/bug-2084580-cb1e8c47501e730c.yaml:
+    fixes:
+    - 'The ``quota set`` and ``limits show`` commands will now check for the
+
+      ``block-storage`` and ``block-store`` service types along with ``volume``,
+
+      ``volumev2`` and ``volumev3``.
+
+
+      [Bug `2084580 <https://bugs.launchpad.net/python-openstackclient/+bug/2084580>`_]
+
+      '
+  releasenotes/notes/bug-27882-402ced7ffe930058.yaml:
+    fixes:
+    - 'The ``--limit`` option of the ``image list`` command was previously ignored.
+
+      [Bug `2004314 <https://storyboard.openstack.org/#!/story/2004314>`_]
+
+      '
+  releasenotes/notes/bug-volume-list-with-project-2dc867c5e8346a66.yaml:
+    fixes:
+    - 'Fix a bug of unable to filter volume list by ``--project``
+
+      and ``--user`` options in the ``openstack volume list``.
+
+      '
+  releasenotes/notes/bug_1602073-5deb58deeafbc8be.yaml:
+    features:
+    - Add "Checksum" column to output of "image list --long" [Bug `1602073 <https://bugs.launchpad.net/bugs/1602073>`_]
+  releasenotes/notes/change-098377fd53cce7a0.yaml:
+    features:
+    - 'Added support for Volume API v3 for the following block storage command
+
+      resources: ``consistency group``, ``consistency group snapshot``,
+
+      ``volume``, ``volume backup``, ``volume host``, ``volume snapshot``,
+
+      ``volume type``, ``volume qos``, ``volume service``,
+
+      ``volume transfer request``. Note that microversion support for Volume API
+
+      v3 is not yet implemented, each command will assume the API version is
+
+      ``3.0``.
+
+      '
+  releasenotes/notes/check-limit-quota-cc7f291dd1b537c1.yaml:
+    features:
+    - Add ``--check-limit`` option to the ``openstack quota set`` command (only for
+      network commands). The network quota engine will check the resource usage before
+      setting the new quota limit.
+  releasenotes/notes/cliff-2.3.0-7ead18fae9ceea80.yaml:
+    fixes:
+    - 'Cliff 2.3.0: The shell formatter would emit invalid shell variable
+
+      names for field names that contain colons (''``:``'') and dashes (''``-``''),
+
+      these are now replaced by underscores (''``_``'').
+
+      [Bug `1616323 <https://bugs.launchpad.net/bugs/1616323>`_]
+
+      '
+  releasenotes/notes/complete_image_switch-203e0b3105a54674.yaml:
+    features:
+    - 'Complete switch from glanceclient to the SDK for image service.
+
+      '
+  releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml:
+    features:
+    - 'Add support for the new ``spice-direct`` console type, as well as the
+
+      exposing the ability for admins to lookup console connection information
+
+      via the new ``console connection show`` command.
+
+      '
+  releasenotes/notes/compute-agent-deff48988e81b30e.yaml:
+    upgrade:
+    - '``compute agent delete`` command now supports deleting multiple agents
+
+      in a single command
+
+      '
+  releasenotes/notes/compute-service-list-forced-down-2b16d1cb44f71a08.yaml:
+    features:
+    - 'Add column ``Forced Down`` to the output of ``compute service list
+
+      --long``. Only available starting with ``--os-compute-api-version 2.11``.
+
+      '
+  releasenotes/notes/config-show-00512dc60882e5c0.yaml:
+    other:
+    - 'The ``configuration show`` command no longer requires authentication.
+
+      This is useful in debugging cloud configurations, particularly
+
+      auth configurations.
+
+      '
+  releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml:
+    upgrade:
+    - 'The ``openstack server set`` command has been extended with a new
+
+      parameter ``--auto-approve`` and the existing ``--state`` parameter
+
+      has been modified to require confirmation before resetting the state.
+
+      '
+  releasenotes/notes/consistency-group-create-opts-aliases-e1c2f1498e9b1d3d.yaml:
+    upgrade:
+    - 'The ``--consistency-group-source`` and ``--consistency-group-snapshot``
+
+      options for the ``consistency group create`` command have been renamed to
+
+      ``--source`` and ``--snapshot``, respectively. Aliases are provided for the
+
+      older variants.
+
+      '
+  releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml:
+    features:
+    - 'Add ``--user`` and ``--type`` option to ``credential list`` command
+
+      to filter list result by different user or type.
+
+      '
+  releasenotes/notes/deprecate-volume-group-create-positional-arguments-89f6b886c0f1f2b5.yaml:
+    deprecations:
+    - "The ``<volume-group-type>`` and ``<volume-type> [<volume-type>...]``\npositional\
+      \ arguments for the ``volume group create`` command have been\ndeprecated in\
+      \ favour of option arguments. For example::\n\n    openstack volume group create\
+      \ \\\n      --volume-group-type <volume-group-type>\n      --volume-type <volume-type>\
+      \ [--volume-type <volume-type> ...]\n"
+  releasenotes/notes/deprecated-quota-class-options-ba33a45caedbdf3e.yaml:
+    deprecations:
+    - 'The ``--class`` options of the ``quota show`` and ``quota set`` commands
+
+      are now deprecated. Quota classes were never fully implemented and the
+
+      compute and volume services only support a single ``default`` quota class
+
+      while the network service does not support quota classes at all. The
+
+      default quotas can be changed on a deployment-wide basis via configuration
+
+      and can be inspected using the ``openstack quota show --default`` command.
+
+      Quotas can still be set on a project-specific basis using the ``quota set``
+
+      command.
+
+      '
+  releasenotes/notes/deprecated-server-create-file-option-80246b13bd3c1b43.yaml:
+    upgrade:
+    - 'The ``server create`` command will now error out if the ``--file`` option
+
+      is specified alongside ``--os-compute-api-version`` of ``2.57`` or greater.
+
+      This reflects the removal of this feature from the compute service in this
+
+      microversion.
+
+      '
+  releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml:
+    features:
+    - "The ``quota list`` command can now provide detailed quotas for the volume\n\
+      service, e.g.::\n\n    $ openstack quota list --detail --volume\n"
+  releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml:
+    fixes:
+    - 'For ``network create`` the
+
+      `--default`` option should be only used for external networks.
+
+      After this release, we enforce this scenario. If a users attempts
+
+      to create an internal default network or update a network to be
+
+      internal default, the command will be denied.
+
+      [Bug `1745658 <https://bugs.launchpad.net/bugs/1745658>`_]
+
+      '
+  releasenotes/notes/drop-py2-421c90fbdf18dbc2.yaml:
+    upgrade:
+    - 'Python 2.7 support has been dropped. The last release of
+
+      python-openstackclient to support Python 2.7 is OpenStack Train. The
+
+      minimum version of Python now supported by python-openstackclient is
+
+      Python 3.6.
+
+      '
+  releasenotes/notes/drop-python-38-9dcbd2b2b51f24f2.yaml:
+    upgrade:
+    - 'Support for Python 3.8 has been dropped.
+
+      '
+  releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml:
+    upgrade:
+    - 'Support for Python 3.9 has been dropped.
+
+      '
+  releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml:
+    fixes:
+    - 'Fixes an issue with python 3.8 and entrypoint loading where the
+
+      new builtin importlib entrypoint support had a different
+
+      attribute api than expected.
+
+      '
+  releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml:
+    features:
+    - 'The ``--network``, ``--port``, and ``--router`` options of the ``floating
+
+      ip list`` command can now be specified multiple times.
+
+      '
+  releasenotes/notes/fix-backup-incremental-d1c1e6886cf32256.yaml:
+    fixes:
+    - 'Fixed issue with creating incremental volume backup.
+
+      Previously, ``incremental`` value was not passed in the
+
+      API request which is now included in the backup
+
+      create request.
+
+      '
+  releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml:
+    features:
+    - 'Add support for compute API microversion 2.47, which changes how flavor
+
+      details are included in server detail responses. In 2.46 and below,
+
+      only the flavor ID was shown in the server detail response. Starting in
+
+      2.47, flavor information is embedded in the server response. The newer
+
+      behavior is now supported.
+
+      '
+  releasenotes/notes/fix-flavor-props-formatting-d21e97745543caa7.yaml:
+    fixes: Fix '-f json' output of the flavor properties to return valid json object
+      instead of stringying it.
+  releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml:
+    fixes:
+    - 'Fixed create image from volume command. If user wants to
+
+      pass ``visibility`` and ``protected`` fields, they need to
+
+      specify volume microversion 3.1 or greater by passing
+
+      ``os-volume-api-version 3.1`` with the command.
+
+      '
+  releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml:
+    features:
+    - '``rbac_object`` parameter in ``network rbac create`` command now can be a QoS
+      policy name.
+
+      '
+  releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml:
+    fixes:
+    - Stream image download to avoid buffering data in memory which rapidly exhausts
+      memory resulting in OOM kill or system crash for all but the smallest of images.
+      Fixes https://storyboard.openstack.org/#!/story/2007672
+    - Restore default behavior of 'openstack image save' to send data to stdout Relates
+      to https://storyboard.openstack.org/#!/story/2007672.
+  releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml:
+    fixes:
+    - 'Fixed the output of ``volume backup restore`` command.
+
+      '
+  releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml:
+    fixes:
+    - 'Fixed the ``openstack volume backup show`` command
+
+      to show a backup by name.
+
+      '
+  releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml:
+    fixes:
+    - 'While uploading a signed image, a private key to sign that image must be
+
+      specified. The CLI client asks for the password of that private key. Due
+
+      to wrong encoding handling while using Python 3, the password is not
+
+      accepted, whether it is correct or not.
+
+      '
+  releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml:
+    fixes:
+    - 'Fixed a bug in "access rule" subcommands where the client logic incorrectly
+
+      assumed that access rules have a "name" property which resulted in
+
+      unpredictable behaviors.  e.g. "access rule delete {non-existent-id}" now
+
+      results in a not-found error instead of sometimes deleting an unrelated
+
+      rule.
+
+      '
+  releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml:
+    features:
+    - Add ``--description`` option to ``flavor set`` command to update the description
+      of the flavor. Only available starting with ``--os-compute-api-version 2.55``.
+    - Add ``--description`` option to ``flavor create`` command to set the description
+      of the flavor. Only available starting with ``--os-compute-api-version 2.55``.
+  releasenotes/notes/flavor-create-with-project-19d41bfa93e3c6d0.yaml:
+    features:
+    - Add ``--project`` and ``--project-domain`` options to the ``flavor create``
+      command. We can use these options to add the flavor access to a given project
+      when we create the flavor.
+  releasenotes/notes/flavor-list-min-disk-min-ram-65ba35e7acc24134.yaml:
+    features:
+    - 'The ``openstack flavor list`` command now accepts two additional
+
+      options, ``--min-disk`` and ``--min-ram``, to filter flavor by
+
+      minimum disk and minimum RAM, respectively.
+
+      '
+  releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml:
+    fixes:
+    - 'The ``openstack server add floating ip`` command has been fixed to handle
+
+      servers with multiple ports attached. Previously, the command was using
+
+      the first port in the port list when attempting to associate the floating
+
+      ip. This could fail if the server had multiple ports and the first port
+
+      in the list was not attached to an external gateway. Another way it could
+
+      fail is if the ``--fixed-ip-address`` option was passed and the first port
+
+      did not have the specified fixed IP address attached to it.
+
+      Now, the ``openstack server add floating ip`` command will find the port
+
+      attached to the specified ``--fixed-ip-address``, if provided, else it will
+
+      try multiple ports until one is found attached to an external gateway. If
+
+      a suitable port is not found in the port list, an error will be returned.
+
+      '
+  releasenotes/notes/floating-ip-set-unset-port-28e33875937b69cf.yaml:
+    features:
+    - 'Add ``floating ip set`` and ``floating ip unset`` commands.
+
+      [:lpbug:`1560297`]
+
+      '
+  releasenotes/notes/floatingip_dns_integration-f26c7575694d098d.yaml:
+    features:
+    - "Add ``--dns-domain`` and ``--dns-name`` options to the \n``floating ip create``\
+      \ commands. These options\nset the DNS domain and name for the floating IP.\n\
+      \nCheck backend available extension and return an error\nmessage if it is missing\
+      \ (instead of a Bad Request HTTP 400).\n[Bug `1547736 <https://storyboard.openstack.org/#!/story/1547736>`_]\n"
+    - 'Add ``--long`` option to the ``floating ip list`` command.  This adds
+
+      ``DNS Name`` and ``DNS Domain`` columns to the floating IP list.
+
+      [Bug `1547736 <https://storyboard.openstack.org/#!/story/1547736>`_]
+
+      '
+  releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml:
+    features:
+    - Add ``--force`` options to the ``openstack quota set`` command. The compute
+      service allows us to to force set a quota, setting a quota value that is less
+      than the amount of the resource currently consumed. Expose this feature by way
+      of a ``--force`` boolean parameter.
+  releasenotes/notes/idp-auth-ttl-6632df5db65a3bdd.yaml:
+    features:
+    - '``identity provider create`` and ``identity provider set`` commands now
+
+      accept the ``--authorization-ttl <VALUE>`` argument, with ``<VALUE>``
+
+      being a non-negative integer.
+
+
+      See `note <https://docs.openstack.org/keystone/latest/admin/federation/configure_federation.html#create-a-mapping>`_
+
+      in Keystone documentations for more details on the meaning of this option.
+
+      '
+  releasenotes/notes/image-import-d5da3e5ce8733fb0.yaml:
+    features:
+    - 'Add ``image import`` command, allowing users to take advantage of the
+
+      interoperable image import functionality first introduced in Glance 16.0.0
+
+      (Queens).
+
+      '
+  releasenotes/notes/image-list-filter-multiple-properties-03c51d43131ee3b6.yaml:
+    features:
+    - 'The ``image list`` command now properly filters images on multiple
+
+      ``--property`` options.
+
+      [Bug `2004290 <https://storyboard.openstack.org/#!/story/2004290>`_]
+
+      '
+  releasenotes/notes/image-list-multiple-tags-a394799c7807f031.yaml:
+    features:
+    - 'The ``image list`` now accepts multiple ``--tag`` options, allowing you to
+
+      filter images on more than one tag.
+
+      '
+  releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml:
+    features:
+    - Add ``openstack image metadef namespace create`` command to create metadef namespace
+      for the image service.
+    - Add ``openstack image metadef namespace delete`` command to delete image metadef
+      namespace.
+    - Add ``openstack image metadef namespace set`` command to update metadef namespace
+      for the image service.
+    - Add ``openstack image metadef namespace show`` command to show metadef namespace
+      for the image service.
+  releasenotes/notes/image-set-to-update-image-membership-68221f226ca3b6e0.yaml:
+    features:
+    - Add support to update image membership with the ``--accept``, ``--reject`` and
+      ``--pending`` options of the ``image set command``.
+  releasenotes/notes/image-stage-ac19c47e6a52ffeb.yaml:
+    features:
+    - 'Added a new command, ``image stage``, that will allow users to upload data
+
+      for an image to staging.
+
+      '
+  releasenotes/notes/image_set_visibility-babf4ff2f687d465.yaml:
+    fixes:
+    - Add ``--community`` and ``--shared`` options to the ``image create`` and ``image
+      set`` commands to allow image owners to share images across multiple projects
+      without explicitly creating image members. “Community images” will not appear
+      in user’s default image listings.
+  releasenotes/notes/implement-system-scope-4c3c47996f98deac.yaml:
+    features:
+    - 'Add support for system-scope to ``role`` commands. This includes the ability
+      to
+
+      generate system-scoped tokens using ``system_scope: all`` in ``cloud.yaml``
+
+      or ``OS_SYSTEM_SCOPE=all`` in an environment variable. Support is also
+
+      included for managing role assignments on the system using ``--system``
+
+      when adding and removing roles.
+
+      [`bp system-scope <https://blueprints.launchpad.net/keystone/+spec/system-scope>`_]
+
+      '
+  releasenotes/notes/implements-hide-image-4c726a61c336ebaa.yaml:
+    features:
+    - 'Add mutually exclusive options ``--hidden`` and ``--unhidden`` to
+
+      ``image set`` command to hide or unhide an image (``is_hidden``
+
+      attribute).
+
+      '
+    - 'Add option ``--hidden`` to ``image list`` command to list hidden images.
+
+      '
+  releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml:
+    fixes:
+    - 'The ``addresses`` and ``flavor`` fields of the ``server show`` command will
+
+      now be correctly rendered as a list of objects and an object, respectively.
+
+      '
+    - 'The ``networks`` and ``properties`` fields of the ``server list`` command
+
+      will now be rendered as objects. In addition, the ``power_state`` field
+
+      will now be humanized and rendered as a string value when using the table
+
+      formatter.
+
+      '
+    - 'The ``usage list`` and ``usage show`` commands will now display the name
+
+      of the project being queried rather than the ID when using the table
+
+      formatter. In addition, the ``server_usages``, ``total_memory_mb_usage``,
+
+      ``total_vcpus_usage`` and ``total_local_gb_usage`` values will only be
+
+      humanized when using the table formatter.
+
+      '
+    - 'The ``policies`` (or ``policy``, on newer microversions) and ``members``
+
+      fields of the ``server group list`` and ``server group show`` commands
+
+      will now be rendered correctly as lists.
+
+      '
+    - 'The ``cpu_info`` field of the ``hypervisor show`` output is now
+
+      correctly decoded and output as an object.
+
+      '
+  releasenotes/notes/ip-availability-ca1cf440f6c70afc.yaml:
+    features:
+    - 'Add ``ip availability list`` and  ``ip availability show`` commands
+
+      [Blueprint :oscbp:`neutron-ip-capacity`]
+
+      '
+  releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml:
+    deprecations:
+    - Deprecate command ``ip floating pool list``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    - Deprecate commands ``ip floating add/remove``. [Blueprint rework-ip-commands
+      `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    - Deprecate commands ``ip fixed add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    - Deprecate commands ``ip floating create/delete/list/show``. [Blueprint rework-ip-commands
+      `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    features:
+    - Add new command ``floating ip pool list`` to list up all floating ip pools.
+      This command is used to replace the old command ``ip floating pool list``. [Blueprint
+      rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    - Add new commands ``server add/remove floating ip``. They are used to replace
+      the old commands ``ip floating add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    - Add new commands ``server add/remove fixed ip``. They are used to replace the
+      old commands ``ip fixed add/remove``. [Blueprint rework-ip-commands `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+    - Add new commands ``floating ip create/delete/list/show``. It is used to replace
+      the old commands ``ip floating create/delete/list/show``. [Blueprint rework-ip-commands
+      `<https://blueprints.launchpad.net/python-openstackclient/+spec/rework-ip-commands>`_]
+  releasenotes/notes/keypair-create-client-side-generation-73d8dd36192f70c9.yaml:
+    features:
+    - 'The ``openstack keypair create`` command will now generate keypairs on the
+
+      client side in ssh-ed25519 format. The Compute service no longer supports
+
+      server-side key generation starting with ``--os-compute-api-version 2.92``
+
+      while the use of ssh-ed25519 is necessary as support for ssh-rsa has been
+
+      disabled by default starting in OpenSSH 8.8, which prevents its use in
+
+      guests using this version of OpenSSH in the default configuration.
+
+      ssh-ed25519 support is widespread and is supported by OpenSSH 6.5 or later
+
+      and Dropbear 2020.79 or later.
+
+      '
+  releasenotes/notes/keypair-support-type-6f7c32aab3b61f7b.yaml:
+    features:
+    - Add ``--key-type`` option to ``keypair create`` command to set keypair type.
+      Can be ssh or x509. Note that ``--os-compute-api-version 2.2`` or later is required.
+  releasenotes/notes/keypair-user-id-db694210695a0ee0.yaml:
+    features:
+    - 'Add ``--user`` option to the ``keypair create``, ``keypair delete``, and
+
+      ``keypair show`` commands. Only available starting with
+
+      ``--os-compute-api-version 2.10``.
+
+      '
+  releasenotes/notes/keystone-endpoint-filter-e930a7b72276fa2c.yaml:
+    features:
+    - 'Add ``endpoint add project``, ``endpoint remove project`` and ``endpoint
+
+      list`` commands to manage endpoint filters in identity v3.
+
+      '
+  releasenotes/notes/keystone-endpoint-group-0c55debbb66844f2.yaml:
+    features:
+    - 'Add endpoint group commands: ``endpoint group add project``, ``endpoint group
+      create``,
+
+      ``endpoint group delete``, ``endpoint group list``, ``endpoint group remove
+      project``,
+
+      ``endpoint group set`` and ``endpoint group show``.
+
+      [Blueprint `keystone-endpoint-filter <https://blueprints.launchpad.net/python-openstackclient/+spec/keystone-endpoint-filter>`_]
+
+      '
+  releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml:
+    features:
+    - 'Add support for list detailed ``quota`` usage for project.
+
+      This can be done by passing ``--detail`` parameter to `quota list` command.
+
+      [Bug `1716043 <https://bugs.launchpad.net/neutron/+bug/1716043>`_]
+
+      '
+  releasenotes/notes/list-subnet-by-pool-id-a642efc13d04fa08.yaml:
+    features:
+    - 'Add ``--subnet-pool`` option to ``subnet list`` to filter
+
+      by subnets by subnet pool.
+
+      '
+  releasenotes/notes/list_role_assignment_names-0db89f50259d4be2.yaml:
+    features:
+    - '[`bug 1479569 <https://bugs.launchpad.net/python-keystoneclient/+bug/1479569>`_]
+      Add an optional ``--names`` argument to the `role assignment list`` command.
+      This will output names instead of IDs for users, groups, roles, projects, and
+      domains.'
+  releasenotes/notes/list_volume_type_access-f7d9aa6159f757ea.yaml:
+    features:
+    - 'Show project access details for private volume type.
+
+
+      An user can list projects which have access to
+
+      a specific private volume type by using
+
+      ``volume type show <volume-type>``
+
+
+      [Bug `1554891 <https://bugs.launchpad.net/python-openstackclient/+bug/1554891>`_]
+
+      '
+  releasenotes/notes/make-snapshot-and-backup-name-optional-01971d33640ef1c8.yaml:
+    fixes:
+    - Make ``--name`` optional in ``volume snapshot create`` and ``volume backup create``
+      commands.
+  releasenotes/notes/migrate-access-rule-to-sdk-923682b4c71fea8a.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``access rule list``
+
+      - ``access rule delete``
+
+      - ``access rule show``
+
+      '
+  releasenotes/notes/migrate-add-fixed-ip-to-sdk-3d932d77633bc765.yaml:
+    features:
+    - 'Switch the add fixed IP command from novaclient to SDK.
+
+      '
+  releasenotes/notes/migrate-agent-commands-1c50ffcb75f91418.yaml:
+    upgrade:
+    - 'The ``compute agent *`` commands have been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-application-credential-to-sdk-c79d8dfc3c8e1d9f.yaml:
+    features:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``application credential create``
+
+      - ``application credential delete``
+
+      - ``application credential list``
+
+      - ``application credential show``
+
+      '
+  releasenotes/notes/migrate-backup-commands-0becc8f18cf9737b.yaml:
+    features:
+    - 'Migrated the following backup commands to SDK:
+
+
+      * Create Backup
+
+      * Show Backup
+
+      * List Backup
+
+      * Restore Backup
+
+      * Delete Backup
+
+      '
+  releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml:
+    features:
+    - 'Migrate openstack server image create from novaclient to sdk.
+
+      '
+  releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``credential create``
+
+      - ``credential delete``
+
+      - ``credential list``
+
+      - ``credential set``
+
+      - ``credential show``
+
+      '
+  releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``domain create``
+
+      - ``domain delete``
+
+      - ``domain list``
+
+      - ``domain set``
+
+      - ``domain show``
+
+      '
+  releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``endpoint create``
+
+      - ``endpoint delete``
+
+      - ``endpoint list``
+
+      - ``endpoint show``
+
+      - ``endpoint set``
+
+      '
+  releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml:
+    upgrade:
+    - 'Migrate ``group`` commands from keystoneclient to SDK.
+
+      '
+  releasenotes/notes/migrate-host-list-show-to-sdk-9b80cd9b4196ab01.yaml:
+    features:
+    - 'The ``host list`` and ``host show`` commands have been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml:
+    upgrade:
+    - 'The ``host set`` command has been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-limits-show-f586c9762dfd7d0c.yaml:
+    upgrade:
+    - 'The ``limits show`` command has been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``region create``
+
+      - ``region list``
+
+      - ``region delete``
+
+      - ``region set``
+
+      - ``region show``
+
+      '
+  releasenotes/notes/migrate-resource-filter-commands-2a353edb965723d1.yaml:
+    fixes:
+    - 'Migrated ``block storage resource filters list`` and
+
+      ``block storage resource filters show`` commands to SDK.
+
+      '
+  releasenotes/notes/migrate-role-assignment-to-sdk-e6e52bef467b4e4c.yaml:
+    features:
+    - 'Migrate ``role assignment`` commands from keystoneclient to SDK.
+
+      '
+  releasenotes/notes/migrate-server-add-network-add-port-to-sdk-7d81b25f59cfbec9.yaml:
+    features:
+    - 'Migrate server add network/port from novaclient to openstacksdk.
+
+      '
+  releasenotes/notes/migrate-server-add-volume-to-sdk-685e036a88839651.yaml:
+    features:
+    - 'Migrate openstack server add volume to using sdk.
+
+      '
+  releasenotes/notes/migrate-server-backup-to-sdk-0f170baf38e98b40.yaml:
+    features:
+    - 'Migrate openstack server backup from novaclient to sdk.
+
+      '
+  releasenotes/notes/migrate-server-evacuate-to-sdk-a0415988ef5451b2.yaml:
+    upgrade:
+    - 'The ``server evacuate`` command has been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-server-events-to-sdk-6a1f5dce582df245.yaml:
+    features:
+    - 'The ``server event list`` and ``server event show`` commands have been
+
+      migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-server-pause-unpause-to-sdk-d74ec8536b764af6.yaml:
+    features:
+    - 'Migrate ``server pause`` and ``server unpause`` commands from novaclient
+
+      to sdk.
+
+      '
+  releasenotes/notes/migrate-server-reboot-to-sdk-a49822810def4c8a.yaml:
+    features:
+    - 'Migrate ``server reboot`` command from novaclient to SDK.
+
+      '
+  releasenotes/notes/migrate-server-restore-to-sdk-4540f26753031779.yaml:
+    features:
+    - 'The ``server restore`` command has been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-server-set-unset-to-sdk-ae32ebcced845b06.yaml:
+    features:
+    - 'The ``server set`` and ``server unset`` commands have been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-server-shelve-unshelve-to-sdk-8fce77586aa68a51.yaml:
+    features:
+    - 'The ``server shelve`` and ``server unshelve`` commands have been migrated
+
+      to SDK.
+
+      '
+  releasenotes/notes/migrate-server-start-stop-to-sdk-55edd4e1ff5e6ac7.yaml:
+    features:
+    - 'Migrate ``server start`` and ``server stop`` commands from novaclient to
+
+      sdk.
+
+      '
+  releasenotes/notes/migrate-server-suspend-resume-to-sdk-fd1709336607b496.yaml:
+    features:
+    - 'Migrate ``server suspend`` and ``server resume`` commands from novaclient
+
+      to sdk.
+
+      '
+  releasenotes/notes/migrate-server-volume-list-update-to-sdk-95b1d3063e46f813.yaml:
+    features:
+    - 'Switch the server volume list and server volume update command from novaclient
+      to SDK.
+
+      '
+  releasenotes/notes/migrate-service-list-delete-set-to-sdk-920cbe0d210af565.yaml:
+    features:
+    - 'Switch the compute service commands from novaclient to SDK.
+
+      '
+  releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``service provider create``
+
+      - ``service provider delete``
+
+      - ``service provider set``
+
+      - ``service provider list``
+
+      - ``service provider show``
+
+      '
+  releasenotes/notes/migrate-service-to-sdk-6ff62ebf7e41db7c.yaml:
+    features:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``service create``
+
+      - ``service delete``
+
+      - ``service set``
+
+      - ``service list``
+
+      - ``service show``
+
+      '
+  releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml:
+    upgrade:
+    - 'The following commands have been migrated to SDK:
+
+
+      - ``trust create``
+
+      - ``trust list``
+
+      - ``trust delete``
+
+      - ``trust show``
+
+      '
+  releasenotes/notes/migrate-volume-attachment-commands-4309409bca1ca5d4.yaml:
+    features:
+    - 'Migrated volume attachment commands to SDK.
+
+      '
+  releasenotes/notes/migrate-volume-backend-commands-259e553e213c71b0.yaml:
+    features:
+    - 'Migrated following volume backends commands to SDK.
+
+
+      * Capability Show
+
+      * Pool List
+
+      '
+  releasenotes/notes/migrate-volume-revert-to-sdk-1e399853d80ba5f8.yaml:
+    features:
+    - 'The ``volume revert`` command has been migrated to SDK.
+
+      '
+  releasenotes/notes/migrate-volume-summary-to-sdk-96ff58f653e0feaa.yaml:
+    features:
+    - 'The ``volume summary`` command has been migrated to SDK.
+
+      '
+  releasenotes/notes/modify-compute-agent-set-77ff894ef62ebbc7.yaml:
+    upgrade:
+    - Migrate command ``compute agent set`` arguments to be optional.
+  releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml:
+    features:
+    - 'Add ``--name-lookup-one-by-one`` option to the ``server list`` command
+
+      that is (mutually exclusive with ``-n | --no-name-lookup``).
+
+      When provided, the names of images and flavors will be resolved one by one
+
+      only for those images and flavors that are needed to display the obtained
+
+      list of servers instead of fetching all the images and flavors.
+
+      Depending on amount of images in your deployment this can speed up the
+
+      execution of this command.
+
+      '
+    - 'When given ``--image`` or ``--flavor`` argument, the ``server list``
+
+      command now resolves only single image or flavor instead of fetching
+
+      all the images or flavors for name lookup purposes.
+
+      '
+  releasenotes/notes/network-add-qos-policy-a25e868e67142f90.yaml:
+    features:
+    - 'Add QoS support for Network commands.
+
+      The new parameter ``qos-policy`` is added to ``network create`` and
+
+      ``network set`` commands. This parameter is the name or the ID of the
+
+      network QoS policy to attach to this network.
+
+      [Bug `1627069 <https://bugs.launchpad.net/python-openstackclient/+bug/1627069>`_]
+
+      '
+  releasenotes/notes/network-flavor-command-support-afe3a9da962a09bf.yaml:
+    features:
+    - 'Add ``network flavor create``,  ``network flavor delete``,
+
+      ``network flavor list``, Add ``network flavor show`` and
+
+      ``network flavor set`` command
+
+      [Blueprint :oscbp:`neutron-client-flavors`]
+
+      '
+  releasenotes/notes/network-ndp-proxy-cli-19afc530fc7061e2.yaml:
+    features:
+    - 'Add new commands ``router ndp proxy create``, ``router ndp proxy set``,
+
+      ``router ndp proxy show``, ``router ndp proxy list`` and
+
+      ``router ndp proxy delete`` to support Neutron NDP proxy CRUD operations.
+
+      '
+    - 'Add new options ``--enable-ndp-proxy`` and ``--disable-ndp-proxy`` to
+
+      command ``router create`` and ``router set`` to support Neutron NDP proxy
+
+      feature.
+
+      '
+  releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml:
+    features:
+    - 'Added four new network agent types to the list method filter:
+
+      ``ovn-controller``, ``ovn-controller-gateway``, ``ovn-metadata`` and
+
+      ``ovn-agent``.
+
+      '
+  releasenotes/notes/network-port-create-vnic-type-vdpa-fc02516cfb919941.yaml:
+    features:
+    - 'The ``port create --vnic-type`` option now accepts a ``vdpa`` value.
+
+      '
+  releasenotes/notes/network-qos-rule-type-filters-47f4911a02011501.yaml:
+    features:
+    - 'Added two new filter flags to ``openstack network qos rule type list``:
+
+      ``--all-supported``, to return any QoS rule type supported by at least
+
+      one loaded driver; ``--all-rules``, to return all QoS rule types
+
+      supported by the current version of Neutron server, regardless of the
+
+      loaded drivers.
+
+      '
+  releasenotes/notes/network-quota-no-force-default-0975bdf15655070c.yaml:
+    upgrade:
+    - The ``openstack quota set`` command previously defaulted to ``--force`` behavior
+      for network quotas. This behavior has now changed and the command now defaults
+      to ``--no-force`` behavior. Users should specify the ``--force`` option if they
+      wish to retain previous behavior.
+  releasenotes/notes/network_dns_integration-5914b2c2be474a41.yaml:
+    features:
+    - 'Add dns-domain support for network commands.
+
+      The new parameter ``--dns-domain`` is added to the ``network create``
+
+      and ``network set`` commands. This parameter sets
+
+      the domain name for the network.
+
+      Check backend available extension and return an error
+
+      message if it is missing (instead of a Bad Request HTTP 400).
+
+      '
+  releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml:
+    features:
+    - 'Add ``network flavor add profile`` and ``network flavor remove profile`` commands.
+
+      [Blueprint :oscbp:`neutron-client-flavors`]
+
+      '
+  releasenotes/notes/neutron_mtu-d87e53e2d76f8612.yaml:
+    features:
+    - 'Add ``--mtu`` option to ``network create`` and ``network set``
+
+      commands, allowing CLI users to set the MTU for Neutron networks.
+
+      '
+  releasenotes/notes/no-force-limit-quota-cc7f291dd1b537c1.yaml:
+    deprecations:
+    - The ``openstack quota set`` command currently defaults to ``--force`` behavior
+      for network quotas. This behavior is now deprecated and a future release will
+      switch to ``--no-force`` behavior. Users should explicitly specify one of these
+      options to prevent a potentially breaking change in behavior.
+    features:
+    - Add ``--no-force`` option to the ``openstack quota set`` command (only for compute
+      and network commands). When specified, the compute and network quota engine
+      will check the resource usage before setting the new quota limit. This is the
+      default behavior of the compute quota engine and will become the default for
+      the network quota engine in a future release.
+  releasenotes/notes/no-project-usage-list-e88eb49aa2e96cf7.yaml:
+    upgrade:
+    - Removed the deprecated command ``project usage list`` in favor of ``usage list``
+  releasenotes/notes/nova-gaps-server-list-to-sdk-88c8bfc10a9e3032.yaml:
+    features:
+    - 'The ``server list`` command now uses the OpenStack SDK instead of the
+
+      Python nova bindings.
+
+      '
+  releasenotes/notes/object-stdout-db76cc500948b0e8.yaml:
+    features:
+    - 'Add support for streaming Swift objects to stdout when using the ``object
+
+      save`` command by specifying ``-`` as a file name: ``--filename -``.
+
+      '
+  releasenotes/notes/optional-volume-name-ffbefe463a598b6c.yaml:
+    features:
+    - 'The ``<name>`` argument for the ``volume create`` command is now optional.
+
+      '
+  releasenotes/notes/options-create-router-97910a882b604652.yaml:
+    features:
+    - 'It is now possible to add an external gateway to a router
+
+      immediately on creation. Previously it could only be done by
+
+      modifying the router after it had been created. This includes
+
+      the options to en- or disable SNAT and to specify a fixed-ip
+
+      on the external network.
+
+      '
+  releasenotes/notes/osc-included-image-signing-a7021a4dbdcf6336.yaml:
+    features:
+    - 'Add options ``--sign-key-path`` and ``--sign-cert-id`` to the ``image create``
+
+      command.  Tthe image must be present on disk, therefore the ``file`` option
+
+      is required:
+
+
+      ``image create --file <filename> --sign-key-path <key-path> --sign-cert-id <secret-id>``.
+
+
+      A prompt for a password ensures, that the private key can be protected too.
+
+      [Bug `2002128 <https://storyboard.openstack.org/#!/story/2002128>`_]'
+  releasenotes/notes/osc4-compute-09246008eff260cb.yaml:
+    upgrade:
+    - 'Remove deprecated ``ip fixed add|remove`` commands.
+
+      Use ``server add|remove fixed ip`` commands instead.
+
+      '
+    - 'Remove deprecated ``ip floating add|remove`` commands.
+
+      Use ``server add|remove floating ip`` commands instead.
+
+      '
+  releasenotes/notes/osc4-identity-6564257c67d43106.yaml:
+    upgrade:
+    - 'Remove deprecated ``role list`` options ``--project`` and ``--user``.
+
+      Use ``role assignment list`` options ``--project`` and ``--user`` instead.
+
+      '
+    - 'Remove deprecated ``user role list`` command.
+
+      Use ``role assignment list`` options ``--project`` and ``--user`` instead.
+
+      '
+    - "Remove deprecated ``service create`` option ``--type``.  \nThe type is supplied\
+      \ as a positional argument in The\n``service create --name <service-name> type``\
+      \ command.\n"
+  releasenotes/notes/osc4-image-e922ee6f8e028648.yaml:
+    upgrade:
+    - 'Remove ``image create|set`` option ``--owner``.
+
+      Use ``--project`` option instead.
+
+      '
+  releasenotes/notes/osc4-network-db2aed696d964ca6.yaml:
+    upgrade:
+    - 'Remove deprecated ``port create|set`` options ``--device-id`` and ``--host-id``.
+
+      Use ``--device`` and ``--host`` options instead.
+
+      '
+    - 'Remove deprecated ``router set`` option ``--clear-routes``.
+
+      Use ``--no-route`` option instead.
+
+      '
+    - 'Remove deprecated ``security group rule create`` options ``--src-ip`` and
+
+      ``--src-group``.
+
+      Use ``--remote-ip`` and ``--remote-group`` options instead.
+
+      '
+  releasenotes/notes/osc4-volume-470422e5a453310e.yaml:
+    upgrade:
+    - 'Remove deprecated ``backup`` commands.
+
+      Use ``volume backup`` commands instead.
+
+      '
+    - 'Remove deprecated ``snapshot`` commands.
+
+      Use ``volume snapshot`` commands instead.
+
+      '
+    - 'Remove deprecated ``volume create`` options ``--project``, ``--user``
+
+      and ``--multi-attach``.
+
+      '
+    - 'Change ``volume transfer request accept`` to use new required option
+
+      ``--auth-key`` rather than a second positional argument.
+
+      '
+  releasenotes/notes/pass_ssh_args-cf26a2ce26ccddaf.yaml:
+    deprecations:
+    - '``openstack server ssh`` options that mirror ``ssh`` options are now
+
+      deprecated (``--login, -l, --port, --identity, --option, -o, -vz``).
+
+      The ``ssh`` equivalent of each deprecated option should be used instead.
+
+      For example ``openstack server ssh instance -- -l user -i key``
+
+      '
+    features:
+    - 'Added the ability to pass arguments through to the ``ssh`` command When
+
+      using ``openstack server ssh``. This allows the user to use any ``ssh``
+
+      option without needing to add that option to the openstack client.
+
+      Existing openstackclient options that mirror SSH options are now
+
+      deprecated.
+
+      '
+  releasenotes/notes/port-device-profile-4a3bf800da21c778.yaml:
+    features:
+    - 'Add device profile to ``port create`` command.
+
+      '
+  releasenotes/notes/port-list-security-group-4af5d2e789174ff9.yaml:
+    features:
+    - 'Added ``--security-group`` option to the ``os port list`` command. This
+
+      option is appendable and multiple security group IDs can be provided.
+
+      '
+  releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml:
+    features:
+    - 'Add ``--enable-uplink-status-propagation`` option and
+
+      ``--disable-uplink-status-propagation`` option to ``port update`` command.
+
+      '
+  releasenotes/notes/project-cleanup-skip-resource-option-4f80db0d8cf36fdb.yaml:
+    features:
+    - 'A new option ``--skip-resource`` has been added to the
+
+      ``project cleanup`` command. This allows to exclude
+
+      certain resources from project cleanups, e. g.
+
+      ``--skip-resource "block_storage.backup"`` to keep
+
+      Cinder backups.
+
+      '
+  releasenotes/notes/properties-with-image-property-field.yaml-c51bf37c3106d6ff.yaml:
+    features:
+    - Support for image search via properties of image. Currently "openstack server
+      create --image-property" only takes image property. Now it can also search image
+      via properties (user defined) too. Story https://storyboard.openstack.org/#!/story/2007860.
+  releasenotes/notes/qos-min-pps-rule-bfe22cea1966c4a0.yaml:
+    features:
+    - 'Add support for QoS minimum packet rate rule to following commands:
+
+      ``network qos rule create``, ``network qos rule delete``,
+
+      ``network qos rule list``, ``network qos rule show`` and
+
+      ``network qos rule set``
+
+      '
+  releasenotes/notes/quota-delete-947df66ae5341cbf.yaml:
+    features:
+    - 'Added a new command, ``quota delete``, that will allow admins delete quotas
+
+      set for projects. Supported by the compute, volume, and network services.
+
+      '
+  releasenotes/notes/quota-network-force-920913981b45ba1a.yaml:
+    features:
+    - Add ``--force`` options to the ``openstack quota set`` command for network service
+      commands. Neutron quota engine now accepts "force" flag to set a new resource
+      quota limit, regardless of the current resource usage.
+  releasenotes/notes/quota-set-default-option-bc26d37dc150533b.yaml:
+    features:
+    - 'The ``quota set`` command now supports a ``--default`` option. When
+
+      provided, this will allow you to set quotas for the default quota class
+
+      which is the only quota class supported by the Compute and Block Storage
+
+      services. This replaces the deprecated ``quota set --class`` option.
+
+      '
+  releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml:
+    features:
+    - 'The ``quota show`` command now allows you to show quotas for a specific
+
+      service using the ``--compute``, ``--volume``, or ``--network`` options.
+
+      '
+  releasenotes/notes/quota-show-usage-option-19b1f59fb5f3498f.yaml:
+    deprecations:
+    - 'The ``--detail`` option for the ``quota list`` command has been deprecated
+
+      for removal. When used without the ``--detail`` option, the ``quota list``
+
+      command returned quota information for multiple projects yet when used with
+
+      this option it only returned (detailed) quota information for a single
+
+      project. This detailed quota information is now available via the
+
+      ``quota show --usage`` command.
+
+      '
+    - 'The ``--project`` option for the ``quota list`` command has been deprecated
+
+      for removal. Use the ``quota show`` command instead.
+
+      '
+    features:
+    - 'The ``quota show`` command now supports a ``--usage`` option. When
+
+      provided, this will result in the command returning usage information for
+
+      each quota. This replaces the ``quota list --detail`` command which is now
+
+      deprecated for removal.
+
+      '
+  releasenotes/notes/rbac-add-address-group-f9bb83238b5a7c1f.yaml:
+    features:
+    - 'Add ``address_group`` as a valid ``--type`` value for the
+
+      ``network rbac create`` and ``network rbac list`` commands.
+
+      '
+  releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml:
+    features:
+    - 'Add ``address_scope`` as a valid ``--type`` value for the
+
+      ``network rbac create`` and ``network rbac list`` commands.
+
+      '
+  releasenotes/notes/rbac-add-security-group-35370701a06ac906.yaml:
+    features:
+    - 'Add ``security_group`` as a valid ``--type`` value for the
+
+      ``network rbac create`` and ``network rbac list`` commands.
+
+      '
+  releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml:
+    features:
+    - 'Add ``subnetpool`` as a valid ``--type`` value for the
+
+      ``network rbac create`` and ``network rbac list`` commands.'
+  releasenotes/notes/recursive-container-delete-983361aa9c35ffed.yaml:
+    features:
+    - 'Add support for recursive container delete.
+
+      [Bug `1542718 <https://bugs.launchpad.net/bugs/1542718>`_]
+
+      '
+  releasenotes/notes/remove-deprecated-quota-show-class-option-2109a6ff7ac18e80.yaml:
+    upgrade:
+    - 'The ``--class`` options of the ``quota show`` command, which was deprecated
+
+      in 6.1.0 (Antelope), has now been removed in favour of the ``--default``
+
+      option. Quota classes were never fully implemented and the compute and
+
+      volume services only support a single ``default`` quota class while the
+
+      network service does not support quota classes at all.
+
+      '
+  releasenotes/notes/remove-deprecated-server-migrate-live-option-28ec43ee210124dc.yaml:
+    upgrade:
+    - 'The deprecated ``--live`` option of the ``server migrate`` command has
+
+      been removed. This was problematic as it required a host argument and
+
+      would result in a forced live migration to a host, bypassing the
+
+      scheduler. It has been replaced by a ``--live-migration`` option and
+
+      optional ``--host`` option.
+
+      '
+  releasenotes/notes/remove-ip-floating-commands-d5363f313e09249a.yaml:
+    other:
+    - 'Remove deprecated ``ip floating`` and ``ip floating pool`` commands.
+
+      '
+  releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml:
+    other:
+    - 'Remove deprecated neutron-lbaas results from ``quota show`` command.
+
+      '
+  releasenotes/notes/remove-osc_password-0767ac78267ef114.yaml:
+    upgrade:
+    - With the change to use keystoneauth plugins the OpenStackClient-specific ``osc_password``
+      authentication plugin has been removed.  The visible difference should only
+      be in the behaviour with poorly configured clouds with old default Keystone
+      values for admin_endpoint and public_endpoint as seen in the version details
+      returned in a GET to the root ('/') route.
+  releasenotes/notes/remove-project-purge-d372374b1a7c4641.yaml:
+    upgrade:
+    - 'The ``project purge`` command has been removed. This has been superseded by
+
+      the ``project cleanup`` command, was not tested, and has not been
+
+      functional for some time hence its removal without a deprecation period.
+
+      The replacement is ``project cleanup``, which is more powerful and more
+
+      flexible.
+
+      '
+  releasenotes/notes/remove-unsupported-set-vlan-transparent-eeff412264ae7c09.yaml:
+    fixes:
+    - 'Remove ``--transparent-vlan`` and ``--no-transparent-vlan``
+
+      from ``network set``, because updating ``vlan-transparent``
+
+      is not supported in Neutron.
+
+      [Bug `1691776 <https://bugs.launchpad.net/python-openstackclient/+bug/1691776>`_]
+
+      '
+  releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml:
+    upgrade:
+    - "Support for the Block Storage (Cinder) v1 API has been officially removed\n\
+      as it had been broken for some time. If you haven't noticed then you likely\n\
+      don't need to do anything. However, in the unlikely event that your cloud\n\
+      is using the Block Storage v1 API - or incorrectly advertises the Block\nStorage\
+      \ v1 API - consider overriding the API version to use v2 as this\nbehaves very\
+      \ similarly. It may also be necessary to set an endpoint\noverride for the Block\
+      \ Storage API if your clouds service catalog is not\nconfigured correctly. For\
+      \ example:\n\n.. code-block:: yaml\n\n    example:\n      regions:\n       \
+      \ - name: regionOne\n          values:\n            block_storage_endpoint_override:\
+      \ 'https://blockstorage.api.cloud.example/'\n      volume_api_version: 2\n\n\
+      If using a public cloud provider, there may also be a profile already\npublished\
+      \ that sets these. These are listed in the `Vendor Support`__\ndoc. For example:\n\
+      \n.. code-block:: yaml\n\n    example:\n      profile: rackspace\n\nAlternatively,\
+      \ consider use versions of OSC < 3.19 and python-cinderclient\n< 5.0 (both Stein),\
+      \ since these were the last versions to fully support\nCinder v1.\n\n.. __:\
+      \ https://docs.openstack.org/openstacksdk/latest/user/config/vendor-support.html\n"
+  releasenotes/notes/rename-server-migrate-confirm-revert-commands-84fcb937721f5c4a.yaml:
+    upgrade:
+    - 'The ``server migrate confirm`` and ``server migrate revert`` commands,
+
+      introduced in OSC 5.0, have been deprecated in favour of
+
+      ``server migration confirm`` and ``server migration revert`` respectively.
+
+      The deprecated commands will be removed in a future major version.
+
+      '
+  releasenotes/notes/rename-server-volume-update-to-server-volume-set-833f1730a9bf6169.yaml:
+    upgrade:
+    - 'The ``server volume update`` command has been renamed to ``server volume
+
+      set`` to better match other commands in OSC. An alias is provided for
+
+      backwards compatibility.
+
+      '
+  releasenotes/notes/rename-snapshot-commands-e0937f7143a4ef55.yaml:
+    deprecations:
+    - Deprecate commands ``snapshot create/delete/list/show/set/unset``. [Blueprint
+      `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+    features:
+    - Add new commands ``volume snapshot create/delete/list/show/set/unset``. They
+      are used to replace the old commands ``snapshot create/delete/list/show/set/unset``.
+      [Blueprint `backup-snapshot-renamed-for-volume-resource <https://blueprints.launchpad.net/python-openstackclient/+spec/backup-snapshot-renamed-for-volume-resource>`_]
+  releasenotes/notes/rename-volume-set-retype-policy-6bacb7dd92f1ad82.yaml:
+    upgrade:
+    - 'The ``volume set --retype-policy`` parameter has been renamed to
+
+      ``--migration-policy`` to better convey the correct meaning of the options
+
+      usage. The migration policy determines whether we are going to perform the
+
+      migration in the retype opearation or not and is not related to the actual
+
+      retype which just changes the volume type of the volume.
+
+      '
+  releasenotes/notes/restore-create-image-duplicates-92e06f64038b120c.yaml:
+    fixes:
+    - 'Fixes default behaviour of `openstack image create` in allowing images
+
+      with the same name. In version 5.2.0 this changed to not allow
+
+      duplicates by default.
+
+      '
+  releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml:
+    features:
+    - 'The router creation command now has the parameter ``--qos-policy``, that
+
+      allows to set a QoS policy for the provided external gateways (one or
+
+      many). It is mandatory to define an external gateway if the QoS policy is
+
+      set.
+
+      '
+  releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml:
+    deprecations:
+    - 'The use of ``router set --route`` to add extra routes next to already
+
+      existing extra routes is deprecated in favor of ``router add route
+
+      --route``, because ``router set --route`` if used from multiple clients
+
+      concurrently may lead to lost updates.
+
+      '
+    features:
+    - 'Add new commands ``router add route`` and ``router remove route`` to
+
+      support new Neutron extension: ``extraroute-atomic`` (see `Neutron RFE
+
+      <https://bugs.launchpad.net/neutron/+bug/1826396>`_).
+
+      '
+  releasenotes/notes/router-gateway-IP-QoS-c8ba95e180bca05f.yaml:
+    features:
+    - 'Add support for attaching and removing qos policy to router gateway IPs.
+
+
+      Add ``--qos-policy`` and ``--no-qos-policy`` options to the
+
+      ``router set`` command.
+
+
+      Add ``--qos-policy`` option to the ``router unset`` command.
+
+      '
+  releasenotes/notes/router-gateway-set-01d9c7ffe4461daf.yaml:
+    features:
+    - 'Add support for setting the gateway information in a router,
+
+      by introducing the new option ``--external-gateway`` in
+
+      ``router set`` command and clearing the gateway information in a router
+
+      by introducing ``--external-gateway`` option in ``router unset`` command.
+
+      [ Blueprint `neutron-client-advanced-router <https://blueprints.launchpad.net/python-openstackclient/+spec/neutron-client-advanced-router>`_]
+
+      '
+  releasenotes/notes/router-port-add-0afe7392c080bcb8.yaml:
+    features:
+    - 'Add ``router add port`` command
+
+      [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+      '
+  releasenotes/notes/router-remove-port-058078c93819b0f4.yaml:
+    features:
+    - 'Add ``router remove port`` command
+
+      [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+      '
+  releasenotes/notes/router-subnet-469d095ae0bac884.yaml:
+    features:
+    - 'Add ``router add subnet`` command
+
+      [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+      '
+    - 'Add ``router remove subnet`` command
+
+      [Bug `1546849 <https://bugs.launchpad.net/bugs/1546849>`_]
+
+      '
+  releasenotes/notes/security-grp-json-fix.yaml-2af1f48a48034d64.yaml:
+    fixes:
+    - The ``openstack server show -f json`` command was not outputting json for security
+      groups, volumes and properties  properly.
+  releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml:
+    features:
+    - Add ``--tag`` option to ``server create`` command to add tags when creating
+      a server. Only available starting with ``--os-compute-api-version 2.52``.
+    - Add ``--tag`` option to ``server set`` command to add a tag to an existing server.
+      Only available starting with ``--os-compute-api-version 2.26``.
+    - Add ``--tag`` options to ``server unset`` command to remove a tag from an existing
+      server. Only available starting with ``--os-compute-api-version 2.26``.
+    - Add ``--tags`` and ``--not-tags`` options to ``server list`` command to list
+      instances with and without the specified tag(s), respectively. Only available
+      starting with ``--os-compute-api-version 2.26``.
+  releasenotes/notes/server-changes-3962541b6ebdbbd8.yaml:
+    other:
+    - 'Changes to ``server`` resource commands:
+
+
+      * Added ``--limit`` and ``--marker`` to ``server list``
+
+      * Added ``server shelve``
+
+      * Added ``server unshelve``
+
+      * ``server resume`` now takes multiple server arguments
+
+      * ``server suspend`` now takes multiple server arguments
+
+      '
+  releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml:
+    features:
+    - 'The ``server create`` command now supports a ``--no-security-group``
+
+      option. When provided, no security groups will be associated with ports
+
+      created and attached to the server during server creation. This does not
+
+      affect pre-created ports.
+
+      '
+  releasenotes/notes/server-create-server-group-a5b630f2a64de28d.yaml:
+    features:
+    - 'The ``server create`` command now accepts a new option, ``--server-group``,
+
+      which is a shortcut for configuring the ``group`` scheduler hint.
+
+      '
+  releasenotes/notes/server-description-ae9618fc09544cac.yaml:
+    features:
+    - 'Add ``--description`` option to ``server create``, ``server rebuild``,
+
+      ``server set`` and ``server unset`` commands.
+
+      [Bug `2002005 <https://storyboard.openstack.org/#!/story/2002005>`_]
+
+      '
+  releasenotes/notes/server-group-create_rule_option-9f84e52f35e7c3ba.yaml:
+    features:
+    - 'Add support for ``--rule`` option for ``server group create``.
+
+      '
+  releasenotes/notes/server-list-host-status-1f542a5bc4292a62.yaml:
+    features:
+    - 'The ``server list`` command will now display ``Host Status`` when the
+
+      ``--long`` option is specified and the compute API microversion is 2.16 or
+
+      greater.
+
+      '
+  releasenotes/notes/server-list-restrict-images-c0b2c4de6f93df33.yaml:
+    features:
+    - 'The ``server list`` needs to query the image service API to retrieve
+
+      image names as part of the response. This command will now retrieve only
+
+      the images that are relevant, i.e. those used by the server included in
+
+      the output. This should result in signficantly faster responses when
+
+      using a deployment with a large number of public images.
+
+      '
+  releasenotes/notes/server-list-selectable-fields.yaml-1d5fb4784fa6f232.yaml:
+    features:
+    - Add ``--c project_id | user_id | created_at`` to ``openstack server list`` command
+      to get these columns as an output.
+  releasenotes/notes/server-migration-by-uuid-59f8272f63abee5d.yaml:
+    features:
+    - 'The ``server migration abort``, ``server migration force complete`` and
+
+      ``server migration show`` commands will now accept a server migration UUID
+
+      in addition to an ID.
+
+      '
+  releasenotes/notes/server-ops-all-projects-2ce2202cdf617184.yaml:
+    features:
+    - 'The ``server delete``, ``server start`` and ``server stop`` commands now
+
+      support the ``--all-projects`` option. This allows you to perform the
+
+      specified action on a server in another project using the server name.
+
+      This is an admin-only action by default.
+
+      '
+  releasenotes/notes/server-rebuild-property-e8c6439b04e27c80.yaml:
+    features:
+    - 'Add ``--property`` option to the ``server rebuild`` command, to provide
+
+      the ability to specify properties of the rebuilt instance.
+
+      [Story `2003979 <https://storyboard.openstack.org/#!/story/2003979>`_]
+
+      '
+  releasenotes/notes/server-rebuild-with-keypair-name-83c1aa20db136d91.yaml:
+    features:
+    - Add ``--key-name`` option to ``server rebuild`` command to set keypair of the
+      server. Note that it requires --os-compute-api-version 2.54 or later.
+    - Add ``--key-unset`` option to ``server rebuild`` command to unset keypair. Note
+      that it requires --os-compute-api-version 2.54 or later.
+  releasenotes/notes/server-set-state-214b12ec2161de4d.yaml:
+    features:
+    - 'Add ``--state`` option to ``server set`` command to set the server to
+
+      active or error state.
+
+      [Blueprint `server-reset-state <https://blueprints.launchpad.net/python-openstackclient/+spec/server-reset-state>`_]
+
+      '
+  releasenotes/notes/service-set-option-61772a8940ad0778.yaml:
+    upgrade:
+    - An exception is not raised by command ``service set`` when nothing specified.
+      Instead, the service is not enabled by default. And if ``--disable-resion``
+      is specified but not ``--disable``, an exception will be raised.
+  releasenotes/notes/show-result-for-server-add-volume-f75277ad58e31024.yaml:
+    features:
+    - 'The ``server add volume`` command will now return details of the created
+
+      volume attachment upon successful attachment.
+
+      '
+  releasenotes/notes/show-server-topology-microversion-v2_78-3891fc67f767177e.yaml:
+    features:
+    - 'Add support for ``openstack server show --topology`` flag, which will
+
+      include NUMA topology information in the output.
+
+      '
+  releasenotes/notes/skip-name-lookups-9f499927173c1eee.yaml:
+    features:
+    - 'Add ``--no-name-lookup`` option to ``server list`` command to skip the lookup
+      of
+
+      flavor and image names.  This can save a significant amount of time on clouds
+      with
+
+      a large number of images.  ``-n`` is an alias for this option.
+
+      '
+  releasenotes/notes/speedup-object-save-6bd59e678a31c3e8.yaml:
+    fixes:
+    - 'Makes ``openstack object save`` much faster when saving an object to disk.
+
+      [Bug `1654645 <https://bugs.launchpad.net/bugs/1654645>`_]
+
+      '
+  releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml:
+    features:
+    - 'Add ``--stateful`` and ``--stateless`` option to the
+
+      ``security group create`` and ``security group set`` commands
+
+      to support stateful and stateless security groups.
+
+      '
+  releasenotes/notes/story-2004346-add-floating-ip-with-no-ports-399c5559e1699816.yaml:
+    fixes:
+    - 'Associating a floating IP with a server using the ``server add floating
+
+      ip`` command requires the server have at least one port associated with it.
+
+      Previously, this was not validated, meaning the operation would silently
+
+      fail. This has been resolved.
+
+      '
+  releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml:
+    fixes:
+    - 'The ``compute service set`` command now properly handles
+
+      ``--os-compute-api-version`` 2.53 and greater.
+
+      [Story `2005349 <https://storyboard.openstack.org/#!/story/2005349>`_]
+
+      '
+  releasenotes/notes/story-2005468-server-use-config-drive-9fc68552365cfefa.yaml:
+    deprecations:
+    - 'The ``--config-drive`` option on the ``openstack server create`` command
+
+      has been deprecated in favour of the ``--use-config-drive`` and
+
+      ``--no-config-drive`` arguments. The ``--config-drive`` option expected
+
+      either a string or bool-like argument, but the nova API has only supported
+
+      boolean values since API v2.1 was introduced.
+
+      '
+  releasenotes/notes/story-2006302-add-boot-from-volume-cd411b1ca776bb3c.yaml:
+    features:
+    - 'Add ``--boot-from-volume`` option to the ``server create`` command
+
+      to create a volume-backed server from the specified image with the
+
+      specified size when used in conjunction with the ``--image`` or
+
+      ``--image-property`` options.
+
+      [Story `2006302 <https://storyboard.openstack.org/#!/story/2006302>`_]
+
+      '
+  releasenotes/notes/story-2006302-support-bdm-type-image-0becfb63bd4fb969.yaml:
+    features:
+    - 'The ``server create --block-device-mapping`` option now supports
+
+      an ``image`` type in addition to ``volume`` and ``snapshot``. When
+
+      specifying an image block device the compute service will create a volume
+
+      from the image of the specified size and attach it to the server.
+
+      [Story `2006302 <https://storyboard.openstack.org/#!/story/2006302>`_]
+
+      '
+  releasenotes/notes/story-2007727-69b705c561309742.yaml:
+    fixes:
+    - 'The ``openstack server group create`` command will now validate the policy
+
+      value requested with ``--policy``, restricting it to the valid values
+
+      allowed by given microversions.
+
+      '
+  releasenotes/notes/story-2010343-b5eb4ed593f51d3f.yaml:
+    fixes:
+    - 'The ``flavor list`` command will no longer attempt to fetch extra specs
+
+      unless they are actually required (by using the ``--long``) option. This
+
+      should significantly improve performance on clouds with a large number of
+
+      flavors.
+
+      [Story `2010343 <https://storyboard.openstack.org/#!/story/2010343>`_]
+
+      '
+  releasenotes/notes/story-2010751-server-rebuild-wait-shutoff-c84cddcd3f15e9ce.yaml:
+    features:
+    - '``openstack server rebuild`` command now fails early if the server is
+
+      not in a state supported for rebuild - either ``ACTIVE``, ``ERROR`` or
+
+      ``SHUTOFF``.
+
+      See `OpenStack Compute API reference for server rebuild action
+
+      <https://docs.openstack.org/api-ref/compute/?expanded=rebuild-server-rebuild-action-detail#rebuild-server-rebuild-action>`_.
+
+      '
+    fixes:
+    - '``openstack server rebuild --wait`` now properly works for servers in
+
+      ``SHUTOFF`` state without hanging.
+
+      [Story `2010751 <https://storyboard.openstack.org/#!/story/2010751>`_]
+
+      '
+  releasenotes/notes/subnet-service-type-8d9c414732e474a4.yaml:
+    features:
+    - 'Add ``--service-type`` option to the ``subnet create``,
+
+      ``subnet set``, ``subnet unset``, and ``subnet list`` commands.
+
+      [ Blueprint `service-subnets <https://blueprints.launchpad.net/neutron/+spec/service-subnets>`_]
+
+      '
+  releasenotes/notes/subnet-set-bbc26ecc16929302.yaml:
+    features:
+    - 'Add ``subnet set`` command.
+
+      [Bug `1542363 <https://bugs.launchpad.net/bugs/1542363>`_]
+
+      '
+  releasenotes/notes/subnet-set-segment-id-4440e433b170f9f3.yaml:
+    features:
+    - Add ``--network-segment`` option to ``subnet set`` command. This enables the
+      possiblity to set the ``segment_id`` of a subnet on update.
+  releasenotes/notes/subnet-unset-5b458cdbaf93d766.yaml:
+    features:
+    - 'Add a new command ``subnet unset`` to clear the information
+
+      of allocation-pools, host-routes or DNS servers from the subnet.
+
+      [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+      '
+  releasenotes/notes/subnet-unset-gateway-20239d5910e10778.yaml:
+    fixes:
+    - 'Add missing ``openstack subnet unset --gateway <subnet-id>``.
+
+      '
+  releasenotes/notes/support-icmp-type-code-zero-cbef0a36db2b8123.yaml:
+    fixes:
+    - Add support to set ``--icmp-type`` and ``--icmp-code`` to 0 in the ``security
+      group rule`` command. [Bug `1703704 <https://bugs.launchpad.net/python-openstackclient/+bug/1703704>`_]
+  releasenotes/notes/support-no-property-in-volume-811e67ff4a199eb6.yaml:
+    features:
+    - 'Add ``--no-property`` option in ``volume set``, this removes all properties
+      from a volume.
+
+      [Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+      '
+  releasenotes/notes/support-no-property-in-volume-snapshot-0af3fcb31a3cfc2b.yaml:
+    features:
+    - 'Add ``--no-property`` option in ``volume snapshot set``.
+
+      [Blueprint  `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
+
+      '
+  releasenotes/notes/support-uplink_status_propagation-4d37452bcf03e0f8.yaml:
+    features:
+    - 'Add ``--enable-uplink-status-propagation`` option and
+
+      ``--disable-uplink-status-propagation`` option to ``port create`` command.
+
+      '
+  releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml:
+    features:
+    - Switch aggregate operations to use SDK
+    - Adds 'aggregate cache image' operation
+  releasenotes/notes/switch-console-log-to-sdk-6ee92b7833364d3d.yaml:
+    features:
+    - 'Switch console logs operation to use SDK
+
+      '
+  releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml:
+    features:
+    - Switch compute.flavor operations from direct API calls (novaclient) to OpenStackSDK.
+  releasenotes/notes/switch-hypervisor-to-sdk-2e90b26a14ffcef3.yaml:
+    features:
+    - Switch hypervisor to the OpenStackSDK
+  releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml:
+    features:
+    - Switch hypervisor operations to consume OpenStackSDK
+  releasenotes/notes/switch-keypair-to-sdk-81e28380e66a7f9c.yaml:
+    Features:
+    - Switch 'openstack keypair' commands to use OpenStackSDK
+  releasenotes/notes/switch-server-lock-to-sdk-d5dd17e4987233a5.yaml:
+    features:
+    - 'The ``server lock`` and ``server unlock`` commands now use SDK.
+
+      '
+  releasenotes/notes/switch-server-migration-show-to-sdk-4adb88a0f1f03f3b.yaml:
+    features:
+    - Finish switching server migration to the OpenStackSDK
+  releasenotes/notes/switch-server-migration-to-sdk-4e4530f787f90fd2.yaml:
+    features:
+    - 'The ``server migration *`` commands now use the OpenStackSDK instead of
+
+      novaclient.
+
+      '
+  releasenotes/notes/switch-server-remove-network-port-to-sdk-829ba711e0e198d5.yaml:
+    features:
+    - 'Switch server remove volume/port to using sdk.
+
+      '
+  releasenotes/notes/switch-server-remove-volume-to-sdk-47e9befd2672dcdf.yaml:
+    features:
+    - 'Switch command server remove volume to using sdk.
+
+      '
+  releasenotes/notes/switch-server-show-to-sdk-44a614aebf2c6da6.yaml:
+    features:
+    - 'The ``server show`` command now uses the OpenStack SDK instead of the
+
+      Python nova bindings. The command prints data fields both by their
+
+      novaclient names used in previous releases as well as the names used in the
+
+      SDK.
+
+      '
+  releasenotes/notes/task-40279-eb0d718ac1959c50.yaml:
+    fixes:
+    - 'Makes ``volume backup record`` commands available in Volume API v3.
+
+      `Task 40279 <https://storyboard.openstack.org/#!/story/2007896>`__
+
+      '
+  releasenotes/notes/unlock-volume-a6990fc3bf1f5f67.yaml:
+    upgrade:
+    - 'The ``volume migrate --unlock`` argument did not actually do anything and
+
+      has now been removed.
+
+      '
+  releasenotes/notes/unset-router-7b0cbd9518bb1de6.yaml:
+    features:
+    - 'Add a new command ``router unset`` to clear the information
+
+      of routes from the router.
+
+      [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+      '
+  releasenotes/notes/unset-subnet-pool-333052dd85b95653.yaml:
+    features:
+    - 'Add a new command ``subnet pool unset`` to clear the information
+
+      of pool-prefixes from the subnet pools.
+
+      [ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]
+
+      '
+  releasenotes/notes/usage-list-all-49ca7a62c50e71d3.yaml:
+    fixes:
+    - 'Compute API v2.40+ returns all matching entities rather than being
+
+      limited to the API server configured maximum (``CONF.api.max_limit``).
+
+      [Story `2005099 <https://storyboard.openstack.org/#!/story/2005099>`_]
+
+      '
+  releasenotes/notes/use_sdk_for_image-f49d2df38e7d9f81.yaml:
+    features:
+    - 'Image service for v2 is switched from using glanceclient to OpenStackSDK.
+
+      '
+  releasenotes/notes/versions-show-12a2443624c83048.yaml:
+    features:
+    - 'A new command, ``openstack versions show`` was added, which will
+
+      provide a list of all versions of all services in the cloud. It
+
+      includes relevant metadata, such as min/max microversion, endpoint,
+
+      status and region.
+
+      '
+  releasenotes/notes/volume-attachment-create-output-fix-56515b8fcdd260b9.yaml:
+    fixes:
+    - 'The ``volume attachment create`` command will now display information
+
+      for successfully created volume attachments. Previously an empty table was
+
+      returned.
+
+      '
+  releasenotes/notes/volume-backend-c5faae0b31556a24.yaml:
+    features:
+    - 'Add ``openstack volume backend capability show <host>`` command that
+
+      provides a list of all capabilities that can be configured
+
+      for the requested backend. The required `<host>` parameter takes the form
+
+      `host@backend-name`.
+
+      '
+    - 'Add ``openstack volume backend pool list`` command that provides
+
+      a list of all backend storage pools. The optional ``--long``
+
+      parameter includes some basic configuration and stats for each pool.
+
+      '
+  releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml:
+    features:
+    - 'Listing volume backups now shows the created_at column when
+
+      volume v3 API is used.
+
+      '
+  releasenotes/notes/volume-migrate-command-52cf6edd62fe17a7.yaml:
+    features:
+    - Add ``volume migrate`` command. [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]
+  releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml:
+    features:
+    - 'The ``volume type create``, ``volume type set``, ``volume type list``
+
+      commands now accept four new options - ``--multiattach``, ``--cacheable``,
+
+      ``--replicated``, and ``--availability-zone`` - which are short cuts for
+
+      setting or filtering on the relevant properties on the volume type.
+
+      '
+  releasenotes/notes/volume-type-list-properties-filter-8532f96d16733915.yaml:
+    features:
+    - 'The ``volume type list`` command now accepts a ``--property <key>=<value>``
+
+      option, allowing users to filter volume types by their extra spec
+
+      properties.
+
+      '
+  releasenotes/notes/volume-v3-default-0ffa9bebb43b5057.yaml:
+    upgrade:
+    - 'Volume commands now default to Volume API 3.  On older clouds
+
+      that do not support Volume 3.x ``--os-volume-api-version 2``
+
+      or the adition of ``volume_api_version: ''2''`` in ``clouds.yaml``
+
+      will be required.
+
+      '
+  releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml:
+    features:
+    - 'Add ``--project`` and ``--project-domain`` option to
+
+      ``volume snapshot list`` command, in order to filter list result
+
+      by different project.
+
+      '
+  releasenotes/notes/warn-on-disk-overcommit-087ae46f12d74693.yaml:
+    upgrade:
+    - 'A warning will now be emitted when using the ``--disk-overcommit``
+
+      or ``--no-disk-overcommit`` flags of the ``server migrate`` command on
+
+      Compute API microversion 2.25 or greater. This feature is only supported
+
+      before this microversion and previously the flag was silently ignored on
+
+      newer microversions. This warning will become an error in a future
+
+      release.
+
+      '
+notes:
+- files:
+  - - releasenotes/notes/add-volume-list-property-option-62008dc24762663b.yaml
+    - !!binary |
+      NTcyZWViNmQzOGY5MjY2OTU4MGIzNGQwZDBhMmIyMTdmYzk5OTE3OQ==
+  version: 8.1.0-9
+- files:
+  - - releasenotes/notes/add-user-project-enabled-filters-9f2090cdcc97b667.yaml
+    - !!binary |
+      MzQ4MzExNzI1OThkMjBlMjExMTQ3YThjMzc1OGQyYjMzODNlYTI1Ng==
+  - - releasenotes/notes/compute-add-validate-console-auth-token-1eda2bd62060ccfa.yaml
+    - !!binary |
+      NWQ3MzBmMzc0YjYzYmJjMjEyMWEwMjU2MzhiN2FiZTc5ZjE1NmY1Mw==
+  - - releasenotes/notes/confirm-reset-state-24497c8b24990aa7.yaml
+    - !!binary |
+      MjVjZDExNzhiMzFhM2Q1NTgyYWI0YWQ3NzUxOGZiNjNhODU2ZmQ4OA==
+  - - releasenotes/notes/drop-python-39-fc95c2d17a862e3e.yaml
+    - !!binary |
+      Y2UyYTI1M2Q1YWM4NjAzYzYxZjRlODY4ZTIxMjYzNTRlMWNmZTRkYg==
+  - - releasenotes/notes/fip-filter-opts-a847f8743fef467f.yaml
+    - !!binary |
+      MDFjMWIxZTM2ZmQ3MTJjYzZkMzM2N2NhMjM1MjVlN2UwYjNlOWY0ZA==
+  - - releasenotes/notes/migrate-domain-to-sdk-da6ec38221e79a37.yaml
+    - !!binary |
+      NGJkZDUxY2JlYTQxZTA4ZjRjNzhiZjA3MWFjNGY3NmQxOGY0MmI0MQ==
+  - - releasenotes/notes/migrate-group-to-sdk-59beef31a7c40bbb.yaml
+    - !!binary |
+      YTJiZTFiMDE0ZTAyMGU5ZWZmYjFhNzJlNDU3ODFlNDcyMzZiOTYwNg==
+  version: 8.1.0
+- files:
+  - - releasenotes/notes/migrate-endpoint-to-sdk-8ca5a34794b6bd7e.yaml
+    - !!binary |
+      Nzc1MGZjMWNmNDVhMzI1NjMyMjUwOTJlYzQ0MmM5NmMzOGVlNjc2OQ==
+  - - releasenotes/notes/network-ovn-agents-bdfced3a6d25e7d2.yaml
+    - !!binary |
+      NzYyYTNiMTBkMTM3MTZlMmJjNGNlZjEyMWQ1YjcwY2VkNjk1OGQ0Mg==
+  - - releasenotes/notes/remove-volume-v1-commands-bfa14e9cae54929f.yaml
+    - !!binary |
+      ZTZiZTlhM2VkZjA5MDQ3NjJjYjY4MTZhMDRiOGQzZDE0NmExZjYzOQ==
+  - - releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml
+    - !!binary |
+      MDc1MTVjZDE2MDI4NDE4NTFkNzJkYWMzMGM3YjEyYWZmZWUyN2JiZQ==
+  version: 8.0.0
+- files:
+  - - releasenotes/notes/bug-1560157-bce572f58b43efa1.yaml
+    - !!binary |
+      NTNhNzljMzNmODhjZWE4M2ZiMmE5MDQwOGRkM2Y1ZThkZDQ4YTJmNQ==
+  version: 2.3.1
+- files:
+  - - releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml
+    - !!binary |
+      MTZmMDA4MzNhNzA4OTM5NzljY2RmN2ZmYjdmNmUxZTc2NTNjZGMyNA==
+  - - releasenotes/notes/allow-custom-logging-12d55f8ed859ff8e.yaml
+    - !!binary |
+      Y2RiNzYzN2I3NjAyN2Y3NGRiOWIyNDAyNmEwNzU3MDg0YTgzMTk1ZA==
+  - - releasenotes/notes/bug-1519502-f72236598d14d350.yaml
+    - !!binary |
+      ZjA5NjBmMGZlZjI2MzI5OGU1NmQ3ZTgxYWNmNTA1OTcwNzNiZWNjNw==
+  - - releasenotes/notes/bug-1519511-74bab0e0d32db043.yaml
+    - !!binary |
+      ODQyODgyZjNjYmZjYTZkZjlhNDJiYzQ5YjBkZWVmZGI4NDUwOWE4ZQ==
+  - - releasenotes/notes/bug-1519512-48624c5a32432a47.yaml
+    - !!binary |
+      ZGNjZGU3MGM1N2JhZjkyNjZhNzk1YTU0MTk4MjM4NTE1ZDdmZGRhNg==
+  - - releasenotes/notes/bug-1538372-ef3a30298357f972.yaml
+    - !!binary |
+      NmIzNTgzYWIwNjQ1OWRhZDhjMmFhMWI3NjI1Mzg1MTYwNDdiOGI0MQ==
+  - - releasenotes/notes/bug-1542359-181d28db21a2358a.yaml
+    - !!binary |
+      MTEyZDdiMGUwOTY2NTk5YWE5NDBkZTRjMDU5OGNlYTc1OTc4MDc4NQ==
+  - - releasenotes/notes/bug-1542362-ddad607f6d3025f0.yaml
+    - !!binary |
+      ODhjOTJiZjcxYWUwMjZiOTBiMDc0MTE3NzJjNjZiNzE4YTdkNTllMQ==
+  - - releasenotes/notes/bug-1543214-959aee7830db2b0d.yaml
+    - !!binary |
+      NDFlMWJkMGJlNjRlMTVhNWUwYzEyYjQ1YmRmM2RjZGU1ZmFiZjI0NA==
+  - - releasenotes/notes/bug-1543226-7d885ecaa3715415.yaml
+    - !!binary |
+      Njg2YTI2OTczODA5ZWFiYTNkZWI5YWVkNjNkYWRkYmEzYmIwNTIxZQ==
+  - - releasenotes/notes/bug-1543672-bad2fc4c6c8f3125.yaml
+    - !!binary |
+      MzU5ZGZhMWEwNjY4MzM1NGFjZTU2OGM3ODcwNmUzZDBhNjM3MmMxNA==
+  - - releasenotes/notes/bug-1544587-ec3ca453c1340b4e.yaml
+    - !!binary |
+      NzlmZDZkM2YyMDc1ZWNkZmRhYzhjODU2YmUxMzViM2ZkMTI2MGViNQ==
+  - - releasenotes/notes/bug-1544589-b9f669ef71aa5e57.yaml
+    - !!binary |
+      YTA0MDEyYzNkNTBjMzYyM2M2OTlmNTdkMGRkMzIwNzgzYjkyZTFjYg==
+  - - releasenotes/notes/bug-1544590-8cf42954e28c2f42.yaml
+    - !!binary |
+      M2M4YmIxNjUxMzdlZTFmMTdkOTljMjcwODk2YjM3ZmI5ZDAwZjA3Yw==
+  - - releasenotes/notes/bug-1546065-41d09ffbd8606513.yaml
+    - !!binary |
+      YmE4MjZmYTA0ZmQ1ZjE2NjU4ZGEwMzE5ZjM0ZTI2ZjE0ZDc3MTZkMg==
+  - - releasenotes/notes/list_role_assignment_names-0db89f50259d4be2.yaml
+    - !!binary |
+      M2E0ODk4OWViMDIxODdmMzg0Y2ZiZjdiYjdjZDU1NTAyNzQxZmM2OA==
+  - - releasenotes/notes/recursive-container-delete-983361aa9c35ffed.yaml
+    - !!binary |
+      ODI4ZjYzZjkwM2VlNzFhOWY2M2ViYWFiMzYzOGZlNDQxNzY4YTM1YQ==
+  version: 2.2.0
+- files:
+  - - releasenotes/notes/add-port-delete-command-4789d3881b186cfc.yaml
+    - !!binary |
+      MzE2OGUyMjk3ZDBiNDhjMjQwYjIyZmI2ZDhjMWI3ZDA1ZGVmMWU2Yg==
+  - - releasenotes/notes/add-port-show-command-de0a599017189a21.yaml
+    - !!binary |
+      OTgxNjIxZTk4NDU5MzRjMTA5YzVlNGFiZDliMmFiNjgyODc0NDM0Ng==
+  - - releasenotes/notes/add-subnet-list-command-970f4b397469bdc6.yaml
+    - !!binary |
+      Mjk5YzU3MTBjNTE4ZDk1MDJhMjNmNTI0MDM2MDA0N2JhYTgxYWM4ZA==
+  - - releasenotes/notes/bug-1486597-857e20262c038514.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1516661-757ef629f899cca3.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1517134-9efecb257910989c.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1519503-978a68a54819dbbc.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1519512-d20f44aca1f9e9b9.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1520003-505af921c8afffc9.yaml
+    - !!binary |
+      OTlmNjc5NTE4OWIxODhiOGM1NjA1MDdiN2Y4MTAxYjFjZDgyMDM5Mg==
+  - - releasenotes/notes/bug-1521492-89b972c6362940a5.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1521492-8cde2601591a8c78.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1522969-63abf273c6e71a07.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1524456-9967fac653c91cb2.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1525805-122e6ce0c3cd4945.yaml
+    - !!binary |
+      Y2Q0OTk4ZWY0MWQ3YmVkOGNmYjNhZTg0OWY1MjJlMDcxNjI5MTNmNQ==
+  - - releasenotes/notes/bug-1527833-42cde11d28b09ac3.yaml
+    - !!binary |
+      OTlmNjc5NTE4OWIxODhiOGM1NjA1MDdiN2Y4MTAxYjFjZDgyMDM5Mg==
+  - - releasenotes/notes/bug-1531360-0f5c62d18088e5b5.yaml
+    - !!binary |
+      NWNiZWNjMTMwZWYyYWFjZDVkOWJkMjY1YjgxNGU2ZjgxNDAzNzRmOQ==
+  - - releasenotes/notes/bug-1532945-1a5485b8d0ebddb8.yaml
+    - !!binary |
+      OTlmNjc5NTE4OWIxODhiOGM1NjA1MDdiN2Y4MTAxYjFjZDgyMDM5Mg==
+  - - releasenotes/notes/bug-1534202-1ba78f0bb744961f.yaml
+    - !!binary |
+      OTlmNjc5NTE4OWIxODhiOGM1NjA1MDdiN2Y4MTAxYjFjZDgyMDM5Mg==
+  - - releasenotes/notes/bug-1540988-17841cfd5accf7f5.yaml
+    - !!binary |
+      NDk5MzY5MzI5YzQ5M2Y5NzM0MjQ4MzkzZmYxOWE4MmI1ZTIyNDA3OA==
+  version: 2.1.0
+- files:
+  - - releasenotes/notes/add-ksa-7f0795157d93a898.yaml
+    - !!binary |
+      ZTYwNGE3MjZiMjYwODk0MWRjMmI2MGNmNGYwNzFlNzc3N2JhMmIxNw==
+  - - releasenotes/notes/bug-1475831-3caafd724d4ed644.yaml
+    - !!binary |
+      ZTYwNGE3MjZiMjYwODk0MWRjMmI2MGNmNGYwNzFlNzc3N2JhMmIxNw==
+  - - releasenotes/notes/bug-1517386-1c0aad8e3203b02b.yaml
+    - !!binary |
+      ZTYwNGE3MjZiMjYwODk0MWRjMmI2MGNmNGYwNzFlNzc3N2JhMmIxNw==
+  - - releasenotes/notes/bug-1519181-932c1ff07ef16666.yaml
+    - !!binary |
+      NTUyZWRlZDlhZDEwMmJmYWZlZTczNGIyYTdhNGM5YWE4ZDgwNmNlNg==
+  - - releasenotes/notes/bug-1519510-3cde4643b33ebb7a.yaml
+    - !!binary |
+      ZTYwNGE3MjZiMjYwODk0MWRjMmI2MGNmNGYwNzFlNzc3N2JhMmIxNw==
+  - - releasenotes/notes/bug-1520115-0367e1c8917dc912.yaml
+    - !!binary |
+      NTUyZWRlZDlhZDEwMmJmYWZlZTczNGIyYTdhNGM5YWE4ZDgwNmNlNg==
+  - - releasenotes/notes/bug-1520541-44d45e4693089c03.yaml
+    - !!binary |
+      NTUyZWRlZDlhZDEwMmJmYWZlZTczNGIyYTdhNGM5YWE4ZDgwNmNlNg==
+  - - releasenotes/notes/no-project-usage-list-e88eb49aa2e96cf7.yaml
+    - !!binary |
+      NTUyZWRlZDlhZDEwMmJmYWZlZTczNGIyYTdhNGM5YWE4ZDgwNmNlNg==
+  - - releasenotes/notes/server-changes-3962541b6ebdbbd8.yaml
+    - !!binary |
+      NTUyZWRlZDlhZDEwMmJmYWZlZTczNGIyYTdhNGM5YWE4ZDgwNmNlNg==
+  version: 2.0.0
+- files:
+  - - releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml
+    - !!binary |
+      ZTc5ZWNhNTVhYWUwMjIwNmJkMTBlNjYzYjE1NDAwNzg0MjRkOTczNA==
+  version: 3.2.1-4
+- files:
+  - - releasenotes/notes/bug-1619274-e78afd7c12ea2c3d.yaml
+    - !!binary |
+      NDhlNmQ4YTM2MWFlODI4YzZmM2MxMmYxZjMyODRkN2U3MWNmNTMzOA==
+  - - releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml
+    - !!binary |
+      NDhlNmQ4YTM2MWFlODI4YzZmM2MxMmYxZjMyODRkN2U3MWNmNTMzOA==
+  - - releasenotes/notes/bug-1642301-ad04424c80e8fe50.yaml
+    - !!binary |
+      NDhlNmQ4YTM2MWFlODI4YzZmM2MxMmYxZjMyODRkN2U3MWNmNTMzOA==
+  version: 3.2.1
+- files:
+  - - releasenotes/notes/bug-1617384-55c88207115e2a5b.yaml
+    - !!binary |
+      ODRjODNmYzNhZWViZjgyMDFhMzAxZjE4NjRjM2I4YTE1NzIxMTFmMQ==
+  version: 3.2.0
+- files:
+  - - releasenotes/notes/add-port-unset-command-8bdaf1fa9c593374.yaml
+    - !!binary |
+      MjMwZDM4ZmI0Y2EwMjM1NzA2YTljZDc2MTc2MjhiODQ0MTMwNzViNw==
+  - - releasenotes/notes/add-server-group-quotas-b67fcba98619f0c9.yaml
+    - !!binary |
+      YjUwYzJiNmE4ODQ3MjE5ZWM2ZDM5MTZmNDI5ZGVjNzdjZjJiYTE4MA==
+  - - releasenotes/notes/bp-backup-snapshot-renamed-for-volume-resource-2d2d13ea8489a61f.yaml
+    - !!binary |
+      MzljNWViOWUzZmU4OWJmMTc3ZTUxM2U0NDdmMjJiNjJmNWU0Nzg1Yw==
+  - - releasenotes/notes/bp-implement-network-agents-5eba48796318f094.yaml
+    - !!binary |
+      NzIyYmU3NWY5Y2ZmZWM3MjQyZDg5M2NhYzIwZDQwYzU3MGFmMzJkNg==
+  - - releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml
+    - !!binary |
+      YWY3YWIwMzY5M2E1NzA4MTAyY2Y2NzQ2NTYzZGEyODllNGMxZTNiNw==
+  - - releasenotes/notes/bp-multi-argument-network-e43e192ac95db94d.yaml
+    - !!binary |
+      MDQxZWE0OTc4Yjk0MTQ5ZDUwMzdiNWFmYzc3NDNkYjkzOWI3NTMzMQ==
+  - - releasenotes/notes/bp-neutron-client-a0552f8ca909b665.yaml
+    - !!binary |
+      NDEyYjI5Yjk3MmU0YTY4Nzc0NzIxNDdmNWI3MTMyMTRhY2UyY2ExMg==
+  - - releasenotes/notes/bp-neutron-client-rbac-bbd7b545b50d2bdf.yaml
+    - !!binary |
+      ZmFjMzIxNDU4MTY2Y2NjZmZjMGViMWQxM2E5ODZhMDFjOWU2ZDMzZQ==
+  - - releasenotes/notes/bp-routed-networks-86a24f34d86fca53.yaml
+    - !!binary |
+      NmE2YjE5MmRkZWI4MGI1MTY3NzhiMWQ2ZTNkMzRmNDI2MWRjYTg1ZA==
+  - - releasenotes/notes/bug-1535213-c91133586e07d71c.yaml
+    - !!binary |
+      MjBhZTU0MDQ1Y2VmMTM2YThkMDY2NWFhYjBkNDU2OThlMTJlZDIxYw==
+  - - releasenotes/notes/bug-1543222-6f8579344ff5c958.yaml
+    - !!binary |
+      Mjc0MDI5MWY0OTE4MDRiZTVmNTIxNzcwZWU3NzNmYTYyODk0ZThhMw==
+  - - releasenotes/notes/bug-1561599-d5f541f08ae6274a.yaml
+    - !!binary |
+      MzM3ZDAxM2M5NDM3OGE0YjNmMGU4ZjkwZTRmNWJkNzQ1NDQ4NjU4Zg==
+  - - releasenotes/notes/bug-1575461-3fed33e53795684a.yaml
+    - !!binary |
+      YjBjMzE3ZWJkZDVlNWYyNjI2Y2UyZmJkNDk1MTQ5MzM2ZmU1ZGY3ZQ==
+  - - releasenotes/notes/bug-1582774-3bba709ef61e33b7.yaml
+    - !!binary |
+      MDk5YTJjMzhiOTlkZmY2YTA5MDljMGEzYmEyOTA5ZjFhZWE1ODY0NA==
+  - - releasenotes/notes/bug-1588588-39927ef06ca35730.yaml
+    - !!binary |
+      OWM2MmFmOGE0MmViZmViNjBkODhmNWFkMGFmN2MxYzJmZDU2Mjg1Mw==
+  - - releasenotes/notes/bug-1589332-2941f5286df7e5d4.yaml
+    - !!binary |
+      OTU0YzI4ZGZhMjFiZTc2YjA1MjJhZjA1MWQ3MWZiOTQ3MDg3N2ExYQ==
+  - - releasenotes/notes/bug-1589348-4a612a4efc7ed0e5.yaml
+    - !!binary |
+      ZWNjZDk0M2FjYzk1MjYzMTFmY2ZjMzE4MjgwYjRiZTUxYzQyYTU2Ng==
+  - - releasenotes/notes/bug-1589935-8a56e6a18d836db9.yaml
+    - !!binary |
+      Y2YxMjIzOTc3MzNiODc5NTUzMDU3N2I3ODI0YWVhZTMwNTcxOTY1OA==
+  - - releasenotes/notes/bug-1592062-e327a31a5ae66809.yaml
+    - !!binary |
+      ZmUwYzhlOTU1YmUwMzMxYWVmOWNjNjg0N2M5YmRkYzQzY2U2NmQ5Mg==
+  - - releasenotes/notes/bug-1592368-a4af69f163a1e208.yaml
+    - !!binary |
+      Yjg3NWY2M2E2ZjJhN2FjMzgxZDRiYjgwYjljMDMyMjcyMTI2ZWY0OQ==
+  - - releasenotes/notes/bug-1592761-f45998453d6801f7.yaml
+    - !!binary |
+      Y2E1ZThlNmM4NTQwZTQ1N2E2MjBjYzkwZDMyMWEwOGU3NDE3ZGUzMg==
+  - - releasenotes/notes/bug-1592906-a5604ec5abe77507.yaml
+    - !!binary |
+      NmRmMDlmZDM3N2Y4NzIzODhkNGY4NTViMDAxYTY1NzhhZTZmYmE0Ng==
+  - - releasenotes/notes/bug-1592906-ad67ce8736f3cd48.yaml
+    - !!binary |
+      NjA2MzlkNzZhNzQyODUyZTE4ZjllMjg4OWM0ODBiZTk1NTk2YzI2OA==
+  - - releasenotes/notes/bug-1592906-e69b37377278d9c2.yaml
+    - !!binary |
+      NGU2MmUxZTJlMThjYjkzYmEwZjg4YmZmODcyNzE4MmIxMDAyZGU0Yg==
+  - - releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml
+    - !!binary |
+      ZmM3MTlmOTk4Y2U1ZjgyNmQ0MmY0OWFlY2Y0ZjQzN2U2ZDA3ODU3YQ==
+  - - releasenotes/notes/bug-1596798-b22fd587bdca8b36.yaml
+    - !!binary |
+      ZGJlZDk3YTI0ZGYyZmI3NGU0OTg5ZmIxNWM5MTIyNTJmOGE4YmIwNw==
+  - - releasenotes/notes/bug-1596821-a07599eb4beb6342.yaml
+    - !!binary |
+      NGU0NmMwNGY5MjFjODE5MjdkZWQ3OGYxN2ZkMjhkNWE1NWViZjllMg==
+  - - releasenotes/notes/bug-1597184-f4fb687b3d4d99d9.yaml
+    - !!binary |
+      NjM2NGRmNGNiZDMzYTIwZWExYzcyOWUwMDMxYjFhZWJkM2ZjZDZkZg==
+  - - releasenotes/notes/bug-1597188-a2ff62b809865365.yaml
+    - !!binary |
+      ZjVhZWY5YWMzNjI1N2NmZDk4MDhjMGRiZGI4MGM1YWRjNDEyODc2Yg==
+  - - releasenotes/notes/bug-1597192-52801f7520287309.yaml
+    - !!binary |
+      MzIyMmZmYzE1N2I2ZTY4NjI0OWZiMmUzZDQzNzVjODkzODRiZmI5Nw==
+  - - releasenotes/notes/bug-1597198-e36b55f3fd185a3a.yaml
+    - !!binary |
+      ZTMxNDA4ZDJhNGM1MjQxODFjMzdlZjU2NWIwMjFjMGI3MjljYmJlMw==
+  - - releasenotes/notes/bug-1597296-9735f33eacf5552e.yaml
+    - !!binary |
+      YzQ1YjFkN2IyMzBlOTAwZDA0MTZhNDk1MzYwN2U1ZDRlMWRjOWNmZA==
+  - - releasenotes/notes/bug-1600196-6a733dd4e3371df7.yaml
+    - !!binary |
+      MzQ4MTI2NTVhNWI0NDYyM2EwNGZjMDVmMWE2YzkxMTBmNGFmYmMyNQ==
+  - - releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml
+    - !!binary |
+      ZTMxMDY4MjIzNTgxMDc1OWMxNzI3ODM2NWZjYjc2ZmFjNDM4ZjU4Mg==
+  - - releasenotes/notes/bug-1605088-fea9347336764469.yaml
+    - !!binary |
+      Y2YyMDIyNTM0Nzc2NjI0MGEyZWJiMTU1ZTZlNDZiODVmODRhM2RkYw==
+  - - releasenotes/notes/bug-1605475-84e649fb8c675737.yaml
+    - !!binary |
+      NjFiOWQ5ZmUyZDBjNmM5OWQ1ZTc3MzYxMTExZjAyYTE5ZDE2OTc4Mg==
+  - - releasenotes/notes/bug-1605774-28aec51f6ec4926e.yaml
+    - !!binary |
+      NzEzZDkyZGY0ZTUzZjc0Njk4YTFmZjJkZmNiNzUxNGZmMjJmMDIzYg==
+  - - releasenotes/notes/bug-1606105-ca06b230e22ab5c6.yaml
+    - !!binary |
+      NWViN2U2MjZiMThiMDMzZjk3ZjNjZjEwZjI3OTE1MjlmOWQ3NTc4OQ==
+  - - releasenotes/notes/bug-1610883-e6345c32a35cc290.yaml
+    - !!binary |
+      ODMxNTQ2ZmI5ZTQxNTAwNzRiYWVjZWU5NDcwYTBiOGQ2ODFlMGY4Ng==
+  - - releasenotes/notes/bug_1602073-5deb58deeafbc8be.yaml
+    - !!binary |
+      OGJiZjMwNDk4ZWIzNDk5MGNiOWJjN2M3YWY0MTgyMTZkNDdmMDQyMQ==
+  - - releasenotes/notes/flavor-create-with-project-19d41bfa93e3c6d0.yaml
+    - !!binary |
+      MDE0ODM1OTMwZDUwMTMwYTJlZmNhMDc4NjkyMDg3NmVmYzYwYThlYg==
+  - - releasenotes/notes/ip-command-rework-8d3fe0858f51e6b8.yaml
+    - !!binary |
+      MGFhMjMwNGYzOGRhMDY5NjU3NjgyN2ZjNGQ3MWYyY2Y3Y2MxM2FkNg==
+  - - releasenotes/notes/list_volume_type_access-f7d9aa6159f757ea.yaml
+    - !!binary |
+      NWU4OTU3ZWY3ZjRhY2VhMWVjZTA2Mzc4YzA1MDAyMWI2NGVhM2Y2Zg==
+  - - releasenotes/notes/modify-compute-agent-set-77ff894ef62ebbc7.yaml
+    - !!binary |
+      MjViZGY2ODExYzcxNDEzOTIxNzc3Y2FkNzNiNmQwMzk0NDQ2MDBmZg==
+  - - releasenotes/notes/remove-osc_password-0767ac78267ef114.yaml
+    - !!binary |
+      Y2NiYjJkZDFlOGFhYTVkMmYzNGEzMDc2M2Y3MTEyNTY4OGM4ZGZhYw==
+  - - releasenotes/notes/subnet-unset-5b458cdbaf93d766.yaml
+    - !!binary |
+      NDViMDI2ZDdjOGU0Njc1YTU5ODE5MmJjZjRjODhmMjIwMDVjYzFkMg==
+  - - releasenotes/notes/unset-router-7b0cbd9518bb1de6.yaml
+    - !!binary |
+      ZWQ2NDc4OGNmMWEyNDdjYTAzMTc0NzcwZDQzZDhjNzgxNmNjMGFkMQ==
+  - - releasenotes/notes/unset-subnet-pool-333052dd85b95653.yaml
+    - !!binary |
+      MDYzYzcyMmExMTAwMzE4ODNlOTYxNTA2NDA5MjY0NGRlNmRmOGRhMg==
+  version: 3.0.0
+- files:
+  - - releasenotes/notes/add-server-backup-e63feaebb6140f83.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/address-scope-delete-multi-31c3af73feb31265.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/bp-routed-networks-3eea4978c93aa126.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/bug-1554886-8e5249a655e7e7b6.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/bug-1575461-4d7d90e792132064.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/bug-1582968-4d44912a033b242c.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/bug-1588384-eb6976fcfb90cb4c.yaml
+    - !!binary |
+      NmYyYzE3MzRlM2Q2NmUyNjFmMjMxNzExNDU1ODIxMzIxYzFmYzI1NA==
+  - - releasenotes/notes/compute-agent-deff48988e81b30e.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/ip-availability-ca1cf440f6c70afc.yaml
+    - !!binary |
+      ZDI0YzI1NWU0MzAyYzM3YjNhNGZhNDA1MWIyNjNiM2Q1ZTBiOWI5Mg==
+  - - releasenotes/notes/server-set-state-214b12ec2161de4d.yaml
+    - !!binary |
+      MWE3Mjg0ZjYzYWQxM2Y0MWM2ZmY0Mjk1ZDY5ZjA2NTMxMDI0MjUyNA==
+  - - releasenotes/notes/service-set-option-61772a8940ad0778.yaml
+    - !!binary |
+      YWMxZDg2YzM0MzMzNzgwZTMwYjkzOTNkMTU1YWU4NGE3NjlhYzIyMg==
+  version: 2.6.0
+- files:
+  - - releasenotes/notes/add-quota-set-for-network-11fcd7b9e08624b5.yaml
+    - !!binary |
+      YjkyY2Y3N2ZiNThiNGFhZmNmNGIzYTFlZjZiODlmZDE1MTY2NTA1Yg==
+  - - releasenotes/notes/bug-1519512-dbf4368fe10dc495.yaml
+    - !!binary |
+      ZmQ1ZmQ5MjRkMTUyMzM4MjA0ZmNmNjk2NzNmZWRkMzFhMzkwNDk3Nw==
+  - - releasenotes/notes/bug-1535239-767e6cf1990eda01.yaml
+    - !!binary |
+      MTg5ZTQ3NzRmODgyNDM2NjllZTFiOTA4OWQ2YzM5MDIxMDk0YzgzZA==
+  - - releasenotes/notes/bug-1536479-d1f03ed2177d06ed.yaml
+    - !!binary |
+      MDg3NTliODUzYTI2MTExNDRhMmQzZjBlOTIxNmQ2ODAxZmMyM2VmMg==
+  - - releasenotes/notes/bug-1542171-fde165df53216726.yaml
+    - !!binary |
+      OTkwMzFjZjFlZDM2YjNjM2I4YzA5ZTJjNjRhYWE0Yjc4OWViMjViOQ==
+  - - releasenotes/notes/bug-1544586-0fe19a567d3e31fc.yaml
+    - !!binary |
+      NDhlYmM0OWYyMDFiYWVhNDQzMTQ2YThkMWMzYjZjYmRlM2IyZjI5Nw==
+  - - releasenotes/notes/bug-1545537-4fa72fbfbbe3f31e.yaml
+    - !!binary |
+      OTkwMzFjZjFlZDM2YjNjM2I4YzA5ZTJjNjRhYWE0Yjc4OWViMjViOQ==
+  - - releasenotes/notes/bug-1550999-5e352a71dfbc828d.yaml
+    - !!binary |
+      OTkwMzFjZjFlZDM2YjNjM2I4YzA5ZTJjNjRhYWE0Yjc4OWViMjViOQ==
+  - - releasenotes/notes/bug-1556719-d2dcf61acf87e856.yaml
+    - !!binary |
+      NTZmOTIyNzA2M2NiODY1OTQ2MDBjY2M4MGM2NjExMDFmMGYwYzJjOA==
+  - - releasenotes/notes/bug-1561838-3a006a8263d7536d.yaml
+    - !!binary |
+      YTVhMzQzYTVhODY2NTgyNDZjYzEzNmEzMzBlZWU5NTFlMzJjN2I1Ng==
+  - - releasenotes/notes/bug-1564460-ab7ad35c02392cb4.yaml
+    - !!binary |
+      YTkwYzgyNGUwNDA3ZjkzMWI1YzQ1ZGY1MzEwM2I0M2FhNTY0ZGUxMg==
+  - - releasenotes/notes/bug-1565034-dd404bfb42d7778d.yaml
+    - !!binary |
+      YmM5M2ViZmU1YzBmYTRkMjliNzlmYTNmZDkzZWM2MDM0MjU5OTdlYQ==
+  - - releasenotes/notes/bug-1566269-2572bca9157ca107.yaml
+    - !!binary |
+      OTkwMzFjZjFlZDM2YjNjM2I4YzA5ZTJjNjRhYWE0Yjc4OWViMjViOQ==
+  - - releasenotes/notes/bug-1572228-03638a7adec5da8b.yaml
+    - !!binary |
+      OWYzZmE1ZWUzYmY4N2M0N2Y3YTM4ZWY3OGY0MDIyYWM0NmIyZjJmNg==
+  - - releasenotes/notes/bug-1572733-874b37a7fa8292d0.yaml
+    - !!binary |
+      MjcwMjRkNzBhZjQ3NTZjYjZlNGIyMTBiMDI1ZWQ3NDI3NTQxZjc3Mw==
+  - - releasenotes/notes/bug-1575478-5a0a923c3a32f96a.yaml
+    - !!binary |
+      NjgxZDZkYzJkZTgzZWYxM2I0ZmIyZmI0YWJlNzBmM2MxY2NiMGUxMA==
+  - - releasenotes/notes/bug-1575624-87957ff60ad661a6.yaml
+    - !!binary |
+      NDUyNGIzNjA1ZmE0MjYwYTJmOTE2NDIxZWViZmM3YTk5YjMyMGU0Yg==
+  - - releasenotes/notes/bug-1581179-4d15dc504777f9e7.yaml
+    - !!binary |
+      NjY4YmMwMjhkMTNiODBkZmM2ZWNiZWY2MTkzNjc4YTk3ZTY0ZmRjMQ==
+  version: 2.5.0
+- files:
+  - - releasenotes/notes/add-disable-reason-6e0f28459a09a60d.yaml
+    - !!binary |
+      YWQ2NzI3ZGY4ODAwYTYxYTU4OTA5OTVhMWU1NzJlNmY1YjliYWIwMQ==
+  - - releasenotes/notes/add-port-commands-a3580662721a6312.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/add-restore-server-d8c73e0e83df17dd.yaml
+    - !!binary |
+      YWQ2NzI3ZGY4ODAwYTYxYTU4OTA5OTVhMWU1NzJlNmY1YjliYWIwMQ==
+  - - releasenotes/notes/bug-1519502-d534db6c18adef20.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/bug-1519511-65b8901ae6ea2e63.yaml
+    - !!binary |
+      YWQ2NzI3ZGY4ODAwYTYxYTU4OTA5OTVhMWU1NzJlNmY1YjliYWIwMQ==
+  - - releasenotes/notes/bug-1519511-65d8d21dde31e5e2.yaml
+    - !!binary |
+      YTdjNzY4NzhkYTAyZGE0MDZjOWNjYmNkNjJjYzQwZGVmMTEwOGZhYQ==
+  - - releasenotes/notes/bug-1519512-4231ac6014109142.yaml
+    - !!binary |
+      ZDkwNjUwNzk2MjE3ZmJiOWNkZDE5Mjk3ZWU2ZmY1OWYwZTAwOTQxMw==
+  - - releasenotes/notes/bug-1519512-48d98f09e44220a3.yaml
+    - !!binary |
+      YTVhOWNhZWEyYjA2YTY5OTUzZjY5MjI4OTg2NmU1OWY1MmQ3OGE0Yw==
+  - - releasenotes/notes/bug-1519512-65df002102b7fb99.yaml
+    - !!binary |
+      OTRjOWNkNWM2NjUxMmQ1MmIzMWRmYWE0MmJjM2QxY2M3ZmQ4MTcwMg==
+  - - releasenotes/notes/bug-1540656-f7b7b7e3feef2440.yaml
+    - !!binary |
+      MjEwOWJjZTg1YTQwZGEzZTNjYmViZWQxY2FjNjYxNjExNTY0Y2NiMg==
+  - - releasenotes/notes/bug-1542364-5d1e93cfd24f0b65.yaml
+    - !!binary |
+      NzFiODkxOTA1NGZjN2NjN2Y5NTAwNmY2ZDdlMmJjZWUxOGM5NTVlNQ==
+  - - releasenotes/notes/bug-1544586-0e6ca9a09dac0726.yaml
+    - !!binary |
+      YWQ2NzI3ZGY4ODAwYTYxYTU4OTA5OTVhMWU1NzJlNmY1YjliYWIwMQ==
+  - - releasenotes/notes/bug-1545537-12bbf01d2280dd2f.yaml
+    - !!binary |
+      YWExNDk1ZTI0MWU5OTkwM2JjODcwNGYxOTgxYTdlMzk0MTgwM2UzNQ==
+  - - releasenotes/notes/bug-1545537-7a66219d263bb1e5.yaml
+    - !!binary |
+      NjdmOGI4OThlYjZkNDhiMTFiOWYwNjI0YWM3MGY2NWM0MzExZjhlOA==
+  - - releasenotes/notes/bug-1545609-bdc1efc17214463b.yaml
+    - !!binary |
+      ZjBjM2I0ZTY5ZGM1NjkzNDMwNTQ0MmI1MDVkNWY1ZjY4NTc5ZjFmMg==
+  - - releasenotes/notes/bug-1554877-7f8479791eab45b7.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/bug-1554889-32ba8d4bfb0f5f3d.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/bug-1556929-edd78cded88ecdc9.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/bug-1559866-733988f5dd5b07bb.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/bug-1560157-bce572f58b43efa1.yaml
+    - !!binary |
+      YjVmMTBmNDNlYjlmZDFhMDQ2YTNlODBkYjA5ZDhiYzhjMzUwYzIxOA==
+  - - releasenotes/notes/bug-1565112-e0cea9bfbcab954f.yaml
+    - !!binary |
+      YmFmOTY0MTFmZWQyMmFkOTdmZjIxOTYwMTgzMGJlNjM1NjNhZTAzYQ==
+  - - releasenotes/notes/bug-1569480-c52e330548bfbd78.yaml
+    - !!binary |
+      M2E0ZDUzYTkzYmI2MmY1YmQyZTIxZGIxNzI3ZWY3NGY3NzEwNzVkOA==
+  - - releasenotes/notes/bug-1571812-49cdce4df5f3d481.yaml
+    - !!binary |
+      NTMwZmU0MjU4OWEyMTM4Mjc4ZjEwMGY3OTFkOGM2ZDNmYmVkODk1MA==
+  - - releasenotes/notes/make-snapshot-and-backup-name-optional-01971d33640ef1c8.yaml
+    - !!binary |
+      MzExZTc3NWM4MTQxOWMzYjI4ZDAzZTYxNmEwZTQxNWE2MTRiOWNmZg==
+  - - releasenotes/notes/router-port-add-0afe7392c080bcb8.yaml
+    - !!binary |
+      MmU5NGYyODAzZmNhMzg2MjU4OWZlMmIxMGM3NmMyZWJjOWUxNzIyOQ==
+  - - releasenotes/notes/router-remove-port-058078c93819b0f4.yaml
+    - !!binary |
+      OGVjZGM1N2VhNjgwYjdlMjA4MzViZWE2OWEyZDE4ZTE0NjBkOTQwNg==
+  - - releasenotes/notes/router-subnet-469d095ae0bac884.yaml
+    - !!binary |
+      OWU0MmRhYTU3N2IwZjE1YzM0OWMyZjRhNzliMzYzMmZmZWM5NzcyMA==
+  - - releasenotes/notes/subnet-set-bbc26ecc16929302.yaml
+    - !!binary |
+      MmI5NWUzNjNkMzI1YzY4NmRiMjI5YTlkYTFkOWEzYTc2NzdlODI5NA==
+  version: 2.4.0
+- files:
+  - - releasenotes/notes/bug-1659967-644a8ee3621c9e81.yaml
+    - !!binary |
+      MjUzYTkyZWM4ZjJiN2JkNWQ4ZjA1NjIxMGRlYTM3NGYyZTJhZTE4NA==
+  - - releasenotes/notes/bug-1711301-17754f487973d4c1.yaml
+    - !!binary |
+      ZjIxMjBmMTVkNTRiYThiMjM3NDg2NjNjODE2NTBlM2ZkN2E2ZWZkMQ==
+  version: 3.8.2
+- files:
+  - - releasenotes/notes/bug-1659878-f6a55b7166d99ca8.yaml
+    - !!binary |
+      MWUzZGM0OGM2NDMwNGViMzc4NjYwY2ViNTMxYWFiM2Q0MmFjMDcxMA==
+  - - releasenotes/notes/bug-1659993-a5fe43bef587e490.yaml
+    - !!binary |
+      MWUzZGM0OGM2NDMwNGViMzc4NjYwY2ViNTMxYWFiM2Q0MmFjMDcxMA==
+  version: 3.8.1
+- files:
+  - - releasenotes/notes/bp-neutron-client-metering-6f8f9527c2a797fd.yaml
+    - !!binary |
+      MTZhZWVlNDMwMzA4ZmQxODYzZDJmOTg5MmYwOWUwZDkyOGEwZTZmMQ==
+  - - releasenotes/notes/bug-1612136-6111b944569b9351.yaml
+    - !!binary |
+      OGJjZmI4MjRjOGYyOTc4YzkzNDg5NjhkM2RhMTM0NWM0NWQ3Yjc2NA==
+  - - releasenotes/notes/bug-1647242-fdc39e564372857b.yaml
+    - !!binary |
+      YzQ2ZjlkYzUwMTQ0MWVmNDQ5ZjQxZTcyNmVjM2NmYmJlOWYzZGU5ZA==
+  - - releasenotes/notes/bug-1647406-c936581034a1b6e4.yaml
+    - !!binary |
+      OTVjODY2MWY4NmU3NGM5ZDUyMTc4NjlhNzQwZGExMTM1MGYxZjBlYg==
+  - - releasenotes/notes/bug-1648087-21dfb7250abfdbe9.yaml
+    - !!binary |
+      NzgwY2UwNzQ1OWY4YzE5NmRiZjI4OTkwOWMzOTBmZjg4YTM4MGUzZg==
+  - - releasenotes/notes/bug-1650026-0ce6a77e69d24424.yaml
+    - !!binary |
+      NGQ5ZGEyYzQwYWUwMjA4NjI1OGNmZGU4NTJiMjk3NzU0ZDgwODVmYQ==
+  - - releasenotes/notes/bug-1655445-96c787e3a51226e0.yaml
+    - !!binary |
+      MDM0MDI3NWZhOWI0OGNkYTVhNWY0MDE1NTM0Y2E4Y2JjYTIzYjNkMg==
+  - - releasenotes/notes/bug-1656767-36a3d4b9fac335c9.yaml
+    - !!binary |
+      ZjM1MzI1MzEyMmNhMzlhZWIwOTI2NTZjZWEwMTFhMDZlNzAxMDNhNA==
+  - - releasenotes/notes/bug-1658147-9de9ae222f9db9ae.yaml
+    - !!binary |
+      NGNiNTYyNjlhZDMwZDBiZDU5Zjc2ODUwNDBhYjA1ODVmMzhjM2IwZg==
+  - - releasenotes/notes/bug-1658582-80a76f6b0af0ca12.yaml
+    - !!binary |
+      NWNmNzdiYjY3MmVlYjI4MzI3Y2FjOGJjMGE4MjI3YzhiNzEzNzgxOQ==
+  - - releasenotes/notes/support-no-property-in-volume-snapshot-0af3fcb31a3cfc2b.yaml
+    - !!binary |
+      MTZhZWVlNDMwMzA4ZmQxODYzZDJmOTg5MmYwOWUwZDkyOGEwZTZmMQ==
+  - - releasenotes/notes/volume_snapshot_list_project-e7dcc07f98d44182.yaml
+    - !!binary |
+      MjdlMGJlMDUxNzE0ZmUxMWEzYjliNTMwNmYyZTBhNzJkOTVmZTJjMw==
+  version: 3.8.0
+- files:
+  - - releasenotes/notes/add-auto-and-none-as-nic-parameter-ed23a6e7f99f250d.yaml
+    - !!binary |
+      ZmYxOGUzZDBlOTMwN2ZiNTA1MTEzYjQ2N2U1OGJkYjYyOTkyZmI4NQ==
+  - - releasenotes/notes/add-network-qos-rule-22cc1ddd509941db.yaml
+    - !!binary |
+      NmIxMTRjZDk4ZjRhMWJjOTVjYjg3MDJkYjAyZWViNjI1YmU2YjNlNw==
+  - - releasenotes/notes/add-network-qos-rule-types-337e464c6e81f29c.yaml
+    - !!binary |
+      OWUxZTdlMWM5ZmRlMmU2MGIyZjk1ZjNiZDAwMGM1OTlhOWUxYzcyYQ==
+  - - releasenotes/notes/add-overwrite-option-to-router-7c50c8031dab6bae.yaml
+    - !!binary |
+      NGQzY2ZiOTE0MmJlODg4NGZhNzRhNmE4YjMyNGRmODY5ZTMyYmEzMA==
+  - - releasenotes/notes/bp-neutron-client-metering-1ee703a48343ece1.yaml
+    - !!binary |
+      MGZiMTM3OGM2Y2E3YTVlYTcxN2VlNjUxZDY0NjAzYjAyNDZmNjczNw==
+  - - releasenotes/notes/bug-1613964-b3e8d9d828a3822c.yaml
+    - !!binary |
+      MmYyNjAzZDkwODk2ZDA3NjVlMWJiMmJiMWNmYjIyM2ZkYmE3NTgzNQ==
+  - - releasenotes/notes/bug-1641868-97c284e33f944c2d.yaml
+    - !!binary |
+      MmU3OGMxMWM4ZDQ4NTE5NWI5YWU0MGI5ZDAwY2YzYTU1N2FlYmQ2ZA==
+  - - releasenotes/notes/bug-1648307-a2c6d7698e927449.yaml
+    - !!binary |
+      YWY3MTI5Y2RhMzNkY2Q0YWM3ODQwOTdkZGI0ZjExOWUxNDVjNDBkNQ==
+  - - releasenotes/notes/bug-1652827-f59bbd1b64df958d.yaml
+    - !!binary |
+      NGQzY2ZiOTE0MmJlODg4NGZhNzRhNmE4YjMyNGRmODY5ZTMyYmEzMA==
+  - - releasenotes/notes/bug-1654221-a564ab75a6afc332.yaml
+    - !!binary |
+      ZDg3NDlmOTE0OGYyYTc4ZjI4ZTkxYzU4ZTY5ODc3OTczNWVhZTRkYw==
+  - - releasenotes/notes/bug-1655537-20b0eb676afa278f.yaml
+    - !!binary |
+      MDI0YmQzYmQ2NjA0OTBlNDU4NDU2YzI4Njc0ZGNkMGFkNGVlMTNjOA==
+  - - releasenotes/notes/bug-1656402-88b12760fb2d4ef9.yaml
+    - !!binary |
+      MzM5YWYyYzIwYmZlNDRhNzcyYTFlMzlmYzhiNzY5ZGIxMTJiNzVjZQ==
+  - - releasenotes/notes/bug-1656572-b40303ae50a41000.yaml
+    - !!binary |
+      ODE5NTI2NTkxZWUyY2RiZjdmMTM4YTA4ZjljMzhiOWM4MDRlNWQzMQ==
+  - - releasenotes/notes/bug-volume-list-with-project-2dc867c5e8346a66.yaml
+    - !!binary |
+      NTFlYTY4YWU5NDhkYTVkNjliMjYyODI3OTYxY2E5YWU5MTE4ZWRiYw==
+  - - releasenotes/notes/image-set-to-update-image-membership-68221f226ca3b6e0.yaml
+    - !!binary |
+      NGQzY2ZiOTE0MmJlODg4NGZhNzRhNmE4YjMyNGRmODY5ZTMyYmEzMA==
+  - - releasenotes/notes/speedup-object-save-6bd59e678a31c3e8.yaml
+    - !!binary |
+      MWNkYzEzMTlkNmNiZmM0MDg3NTUxZTViZjBhOTg3NWMwMTZlY2ExYw==
+  version: 3.7.0
+- files:
+  - - releasenotes/notes/bp-cinder-command-support-82dbadef47454c18.yaml
+    - !!binary |
+      ZDA4M2RkYjEyZjRiOGViMGQ3MmJiNGZmNjAxMTNjZDA5MDRkOGMxZA==
+  - - releasenotes/notes/bp-cinder-command-support-ff7acc531baae8c3.yaml
+    - !!binary |
+      N2U1YTk4YmNhOTFlMDczNGYzNDQwZmRiZWIxMmNkNTkyNzNjZDZhNA==
+  - - releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml
+    - !!binary |
+      ZDEyYWE4NmY3YzRjYWRiNDIzNTUzZDYwN2FlNDA3OGYyY2I4YTk2Mg==
+  - - releasenotes/notes/bug-1650342-22cb88ef37a41872.yaml
+    - !!binary |
+      NjMzNzdmMjVmYzdkZmFlMTUxYmFiMmY2ZTgyMDAyYTlhMTk0NGU5Mw==
+  - - releasenotes/notes/router-gateway-set-01d9c7ffe4461daf.yaml
+    - !!binary |
+      NGE1YmY4ZDJhNThmZGUxZDZjYmJkMmJiMjdjM2ViNmZhYmU1OWMzYQ==
+  version: 3.6.0
+- files:
+  - - releasenotes/notes/add-dns-nameserver-overwrite-option-b866baeae12f9460.yaml
+    - !!binary |
+      MTFhNzYyZTAzYzNkNTNiNDU4ODgzODdmM2M1NDcyYTM3ZDlkOWY2OA==
+  - - releasenotes/notes/add-network-service-provider-c161a4a328a8a408.yaml
+    - !!binary |
+      MTFhNzYyZTAzYzNkNTNiNDU4ODgzODdmM2M1NDcyYTM3ZDlkOWY2OA==
+  - - releasenotes/notes/add-port-security-enabled-to-port-set-82b801d21d45e715.yaml
+    - !!binary |
+      MTFhNzYyZTAzYzNkNTNiNDU4ODgzODdmM2M1NDcyYTM3ZDlkOWY2OA==
+  - - releasenotes/notes/bp-cinder-command-support-413b6d80232f8ece.yaml
+    - !!binary |
+      NGIxNGYzZDBjYjI2ZGM4OWQ3YjYyYzcwMzAyZWVmYWFiYzdjZjJlMw==
+  - - releasenotes/notes/bp-cinder-command-support-7e3ae1fb4cd90407.yaml
+    - !!binary |
+      NzFlNmQ0NDQ3NjdhMjk2NjQ4MjFhYjE5MGUwNzM2MDg4ZDhjY2ZiYQ==
+  - - releasenotes/notes/bug-1597195-54ff1ecf381899f6.yaml
+    - !!binary |
+      YmJmZDhjYjQ2YmM3NDkzOTcxMTczZjFjYmM3NzRlZjQ2OTdkZGZlNA==
+  - - releasenotes/notes/bug-1612136-63aac6377209db38.yaml
+    - !!binary |
+      ZGY1ZjEyYjEzNWYyNzNlMzkxNmU3YmYzMDBmYTc2ODhhMTgwZWEwMg==
+  - - releasenotes/notes/bug-1613231-386b2b1373662052.yaml
+    - !!binary |
+      Y2UwNzlkMjI2MTdmMzEyOWJmZGY1MTY1YjlmMTI0ZDdjYzdkYmMyZQ==
+  - - releasenotes/notes/bug-1613964-837196399be16b3d.yaml
+    - !!binary |
+      MTkwNzIyMDExM2VmZTk0MjVhNmNjN2Y1MmNlODdkZDRlODIyMzNjNw==
+  - - releasenotes/notes/bug-1613964-86e0afe0e012a758.yaml
+    - !!binary |
+      NGRjNzhlNDI2NWY2MDM1NmVhNDUzYzdmNTJmY2RhZWVjZWM1OGZjYg==
+  - - releasenotes/notes/bug-1614379-d8e2815804d53cef.yaml
+    - !!binary |
+      NDc3MTZkMWFkMzJiN2M4NzlmNmI1NzM2Njg3YmUxNTUzZjZmYmZiNg==
+  - - releasenotes/notes/bug-1614379-da92ded6d19f5ad5.yaml
+    - !!binary |
+      ODM5YzVmN2E4NGI0OGNlY2JjODA2MDZlODk0Yjc5MDZmYTAxZDY2Yg==
+  - - releasenotes/notes/bug-1618676-04ff0f335b670567.yaml
+    - !!binary |
+      NzM1N2IyNGQzYTYzYmU2MTJhYTMyYzkwMWUxNTQyNGZmOTJiZWNhMA==
+  - - releasenotes/notes/bug-1619274-e78afd7c12ea2c3d.yaml
+    - !!binary |
+      MTFhNzYyZTAzYzNkNTNiNDU4ODgzODdmM2M1NDcyYTM3ZDlkOWY2OA==
+  - - releasenotes/notes/bug-1639231-21823768bd54170a.yaml
+    - !!binary |
+      YTdhMGQwYzYxYTZhODhlMDQ0Yjc4MWJiYzQ5MDNjZGNmYzkxOWU1NQ==
+  - - releasenotes/notes/bug-1642238-3032c7fe7f0ce29d.yaml
+    - !!binary |
+      MzkwNzEzN2Y1ODI0ZTM1OWJjZGNmY2RkOGFiM2QxNWE4M2QxMGJjYQ==
+  - - releasenotes/notes/bug-1642301-ad04424c80e8fe50.yaml
+    - !!binary |
+      MTFhNzYyZTAzYzNkNTNiNDU4ODgzODdmM2M1NDcyYTM3ZDlkOWY2OA==
+  - - releasenotes/notes/bug-1642772-19f53765bef8ee91.yaml
+    - !!binary |
+      NGJjZTcxNjczMzg5MDhiMDgyZWI4ZWE5NDZhZGNkNjAxMDllMDkwNw==
+  - - releasenotes/notes/bug-1643861-b17ad5dfcb4304ff.yaml
+    - !!binary |
+      NWUwNzBjMzZhMTc2ZWRmNDdlYzA4MzJlZjkwNjM2ZWU2NzIwZGVmNw==
+  - - releasenotes/notes/bug-1645252-219bfd50c8f04846.yaml
+    - !!binary |
+      NmNhNGRjMzUzM2QwMDk4NjZmODI1MTVjMzRjYjM4ODFmOTkzYzc1MA==
+  - - releasenotes/notes/network-add-qos-policy-a25e868e67142f90.yaml
+    - !!binary |
+      NDEzMjM5MmMyZmQ4MzM3ZDE4Mjk2YzMzZjA3YzRhODliOGE1OGJkYQ==
+  - - releasenotes/notes/rename-snapshot-commands-e0937f7143a4ef55.yaml
+    - !!binary |
+      MTFhNzYyZTAzYzNkNTNiNDU4ODgzODdmM2M1NDcyYTM3ZDlkOWY2OA==
+  version: 3.5.0
+- files:
+  - - releasenotes/notes/bug-1642301-18b08e0cd4b11687.yaml
+    - !!binary |
+      NjFjYzU0NjQ3NTBlMDNhNDQ1MzY2NDJjZGM0OTNjZjgxZGVkMjM2Ng==
+  version: 3.4.1
+- files:
+  - - releasenotes/notes/add-ha-to-router-update-6a38a73cc112b2fc.yaml
+    - !!binary |
+      YmFlMDljM2MzZmFjMjEwZjQ4MzlhOGE1MWRmYjUxZTJkYWQ2OWFhNw==
+  - - releasenotes/notes/add-network-qos-policy-b8ad1e408d73c279.yaml
+    - !!binary |
+      MzIwNWRhZDE2MWM2YzdiY2FmMTZmOTg1MTIxMjE3YjhjZjMyMGFmMA==
+  - - releasenotes/notes/backup_list_all-projects_option-4bb23e0b9b075cac.yaml
+    - !!binary |
+      NzQzNjBlMDBmNTFiZDZiZTI3NWFlNWU3ZTVmYzBlMWVlNzY1YjU0Zg==
+  - - releasenotes/notes/bp-cinder-command-support-3db775ba331e113d.yaml
+    - !!binary |
+      ZGFmZmNlM2E2YTMxYWM1OWVlMTBlM2NjOGZlNDIxMzIwZGExNzA0YQ==
+  - - releasenotes/notes/bp-neutron-client-descriptions-b65dd776f78b5a73.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bug-1518059-e2dbe6e4b2473f10.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bug-1566090_64726dc7df5b1572.yaml
+    - !!binary |
+      OGY4YTg0NDhhNGFkYzFkMjUwYzI1MzczODY4OGZmNDZlNjQ1NjYxNg==
+  - - releasenotes/notes/bug-1607959-a52aa93e3793f28a.yaml
+    - !!binary |
+      Mzc3MGFkMDhiMjFiNWFkN2RkNTQzMGU4MTBmMTYxODQzNWIyNjlkNQ==
+  - - releasenotes/notes/bug-1612136-051b5f94796e3b51.yaml
+    - !!binary |
+      NjZhMDRhYmQ1ODFlMDNlNWU3MWE2Yjc1NWUxYjRkY2UxODU2ZWY0MQ==
+  - - releasenotes/notes/bug-1613533-93279179c6f70117.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bug-1613995-10bb3895d702c063.yaml
+    - !!binary |
+      MmMxMjgyY2VjZjMzMTYyYjU0ODNmNWNiNTU4Zjk4Mzk1OTQ1MzgwYg==
+  - - releasenotes/notes/bug-1631471-beb0a1c9b4a932cb.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bug-1634333-a2b04d33ca39440e.yaml
+    - !!binary |
+      YTFlMzA1NjQxNDMwYWY0OGI3MmM5NDFmODdjN2ZmY2MxODJiM2Y5YQ==
+  - - releasenotes/notes/bug-1634672-7ce577f3adc34eed.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bug-1635580-54e0039b469ad5a6.yaml
+    - !!binary |
+      OTYwYjI2NThkYzZhYjFmODJiNzhkYmM1MzEzODY1NDRkMzAyZjA5ZQ==
+  - - releasenotes/notes/bug-1637074-1b0e409f30f715ca.yaml
+    - !!binary |
+      OGNhMWNjNjM3MDEzOTcyNDkxNzQ0YjgzMThkMzBlOTI1NmJjNDE2NQ==
+  - - releasenotes/notes/bug-1637365-b90cdcc05ffc7d3a.yaml
+    - !!binary |
+      MGFjNDM3MGMwOTU2N2I4MGNkYTg0ZDAyMjA2ODY0MjA0NzU3NmUzMg==
+  - - releasenotes/notes/bug-1637945-f361c834381d409c.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bug-1639712-a7b9d1a35a042049.yaml
+    - !!binary |
+      ZTA3YjBlMDkxOTc4NGI0OGRjNDdhZTljZDg4MzYzNDJiOGMxMzQ4MA==
+  - - releasenotes/notes/cliff-2.3.0-7ead18fae9ceea80.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/fix-network-rbac-create-d1f4de77ad2dd421.yaml
+    - !!binary |
+      NTdkNWY5NDU0MDI2ODFlNWY3ZDYyYjljYTk5ZmMyMjk5MjdjYzc4NA==
+  - - releasenotes/notes/volume-migrate-command-52cf6edd62fe17a7.yaml
+    - !!binary |
+      ZDdjOGJiODhlNGExMTdkOGFiNmE1M2MzYTdkMTRjYzdhNDEwNWVkYQ==
+  version: 3.4.0
+- files:
+  - - releasenotes/notes/add-network-list-option-to-ports-9d101344ddeb3e64.yaml
+    - !!binary |
+      NTU0NjA3ZWIzZGFiODc5ZGE4ZTE3MmVhY2I3MjkzMGU1NGYwYWNmNA==
+  - - releasenotes/notes/bp-allow-overwrite-set-options-190a9c6904d53dab.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml
+    - !!binary |
+      M2VmN2UyOWRkMDFhODQ4YWQwOGNlMWI2NmRlYjljNWMzYjFhNGIxZQ==
+  - - releasenotes/notes/bp-network-command-options-2-e7b13a6a09f5d21e.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bp-neutron-client-descriptions-a80902b4295843cf.yaml
+    - !!binary |
+      YWQ1YWU4M2EzNGU1NTVkYWJlYjI3NjFkM2Q4ZjNjN2YxZGJhYzJmOA==
+  - - releasenotes/notes/bp-routed-networks-3b502faa5cd96807.yaml
+    - !!binary |
+      MjU2ZWM2NmY3OWY5OGI0MTQ5N2U4OTM3OTExNjA0YmFjN2RkZWFiYg==
+  - - releasenotes/notes/bp-support-no-property-in-aggregate-b74a42e00a65d14a.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bug-1204956-af47c7f34ecc19c3.yaml
+    - !!binary |
+      NmYzMjZhY2QyNjBkMDM1Y2IwMjRmMGM1ZTNlZjIyMzcyNzdkOGIzNw==
+  - - releasenotes/notes/bug-1535704-d6f013bfa22ab668.yaml
+    - !!binary |
+      NmE5MTRkMDA1NmU4MTBlMWVmMzdlYWY0ZjAxY2Q1Yzg1MjE3YWJhNg==
+  - - releasenotes/notes/bug-1578819-d1efccfefb18356d.yaml
+    - !!binary |
+      OWM0NzNmNDc1ZDJiYjdhZGFkYzY1YTc1MjViOTNkYjg0ZjEwYmVmOQ==
+  - - releasenotes/notes/bug-1588171-61214d0ea482988c.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bug-1607972-a910a9fbdb81da57.yaml
+    - !!binary |
+      NzgzMTJjYTlhZmVhMjJmNjUxMWYyNDIxZGNjYjA3MzZmMzk0ZTljOA==
+  - - releasenotes/notes/bug-1609233-90b2ddf8d941050e.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bug-1609767-0602edc4408c2dc6.yaml
+    - !!binary |
+      NmZiYTcxNjNlODVhNDM2ZDFmZTA2NjBkOTkzMmE1M2QwNmIxYTM0Mw==
+  - - releasenotes/notes/bug-1610161-7c34c7b735701bd4.yaml
+    - !!binary |
+      ZTJmYzQzNmQ1M2Y1M2QwOTkzZmMwYjlkZDI5ZjQwMmU2YzdmOGJjMQ==
+  - - releasenotes/notes/bug-1610883-38929f6fc2eefc9a.yaml
+    - !!binary |
+      NWVjNDM1ZTcwNmQxMzdhZmI3MTRjZmQ1YzVkZGJkNDBkODEwN2E5ZQ==
+  - - releasenotes/notes/bug-1612484-e8605ad8966a455e.yaml
+    - !!binary |
+      Njk4NmEzMmUxY2Q2ZDBjMGJkZjk3M2U1ZDRlNGJjYjNkMWY0NTIzNQ==
+  - - releasenotes/notes/bug-1613261-290a64080fead6c0.yaml
+    - !!binary |
+      ZGRmODQ0MjlmMjk3YjM0Y2U3MDY3MjUwZDgzNGVhODk3ZTM3ZjM3Yw==
+  - - releasenotes/notes/bug-1613597-b1545148b0755e6f.yaml
+    - !!binary |
+      ODE0MzFkMjRhOWY5NGY1NmM0YzM5Y2IxMmJmODQ2ODcxZjYyMzBkOA==
+  - - releasenotes/notes/bug-1613926-2d0e405831c0b5a9.yaml
+    - !!binary |
+      NWVjNDM1ZTcwNmQxMzdhZmI3MTRjZmQ1YzVkZGJkNDBkODEwN2E5ZQ==
+  - - releasenotes/notes/bug-1613964-e5760f4825f1e043.yaml
+    - !!binary |
+      OGQ2M2I4YjI2M2NhNDAxMTc2MWIwNjIzMzFkNTNkOWI1M2I1MDMxZA==
+  - - releasenotes/notes/bug-1614385-460b5034ba372463.yaml
+    - !!binary |
+      OTZhOGVkNDM1YzdlNTU2MzNjMDBkYmIxMjgzNDc3ZmYxMWNmMzVmOQ==
+  - - releasenotes/notes/bug-1614458-c42be5738f447db8.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bug-1614823-e89080342f25f2c0.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bug-1620922-7f27942dc00f7108.yaml
+    - !!binary |
+      NTIzMWFkZTI3YzhhMDhlM2Q3ZmQ1NTczZDRkZGE2ZmE0N2QwYWU2Nw==
+  - - releasenotes/notes/bug-1622565-2e715aff8b054401.yaml
+    - !!binary |
+      NWVjNDM1ZTcwNmQxMzdhZmI3MTRjZmQ1YzVkZGJkNDBkODEwN2E5ZQ==
+  - - releasenotes/notes/bug-1624085-7cf296649277f405.yaml
+    - !!binary |
+      NWVjNDM1ZTcwNmQxMzdhZmI3MTRjZmQ1YzVkZGJkNDBkODEwN2E5ZQ==
+  - - releasenotes/notes/bug-1627913-2adf4182977e5926.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml
+    - !!binary |
+      NzYyZjJmMmMzNDgxNGI4YmZjNjE1Njk2OTE4ZDhjYjQ5YjkzYTFkZA==
+  - - releasenotes/notes/subnet-service-type-8d9c414732e474a4.yaml
+    - !!binary |
+      Y2Y5YWQwOGFiNmZkNWU2ZWQ1ZjY4MjA4YTM5YjAwMTRiMGFmNWY4YQ==
+  version: 3.3.0
+- files:
+  - - releasenotes/notes/bug-1711301-633255f813c71d2a.yaml
+    - !!binary |
+      OGVjZWQ1MDUzMjlhMzI1MzNiMTE1NDcwMDMwMjc4MGNhNWFmNTFlZg==
+  - - releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml
+    - !!binary |
+      YjljNTA5NGVkZTUwMzEwOTk1NWViOTBmZTAwMDdlMzQzZjdiYjkwMw==
+  - - releasenotes/notes/bug-1732938-868963acedaa307e.yaml
+    - !!binary |
+      OGVjZWQ1MDUzMjlhMzI1MzNiMTE1NDcwMDMwMjc4MGNhNWFmNTFlZg==
+  version: 3.12.1
+- files:
+  - - releasenotes/notes/add-is-default-to-network-qos-policy-89b11d4df032a789.yaml
+    - !!binary |
+      YzE3ODE5YWI1OGRiN2RlZDMwNjQ0ZDYzNTc1ZDQ3ZWUzYzk2M2FkYQ==
+  - - releasenotes/notes/add-virtio-forwarder-vnic-type-bad939c6a868b9e9.yaml
+    - !!binary |
+      Y2Y1ZGZhNzdlMTdkMjczYWFlYmNhMjFhMGI0NDkwMmQ1ODdmYWMwNA==
+  - - releasenotes/notes/bp-network-l3-adv-commands-cc1df715a184f1b2.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bp-neutron-client-tag-ff24d13e5c70e052.yaml
+    - !!binary |
+      NTdlNTg0MDcxMGMzYjJiNzRkMzFiZmQ2YTBkYTczOWUwZmM3NDdlZA==
+  - - releasenotes/notes/bug-1584596-5b3109487b451bec.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bug-1614121-a3c5b6892074d5ae.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bug-1640086-21d7e5f2ce18f53c.yaml
+    - !!binary |
+      Njk2MmNjOTYzZTZlMTdlNzA5NTI0ZWNmNmEzOTVlMmQwYzhiODM3MA==
+  - - releasenotes/notes/bug-1657956-977a615f01775288.yaml
+    - !!binary |
+      NmFjZWNhMjE4YWY3ZDFkMmM3MDhmZGU0OGYxYTVmMmI3OThiYzQyMQ==
+  - - releasenotes/notes/bug-1658189-d2b390ad74c96c79.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bug-1667266-6497727abc2af9a5.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bug-1667294-f92efa49627eb00a.yaml
+    - !!binary |
+      ZWI3OTNkYzhjNmE4YmQzMGU2MTJmMTlmMzA4MDg1MjhiMTBlYjM0NA==
+  - - releasenotes/notes/bug-1684989-3bda158a822d2f73.yaml
+    - !!binary |
+      MWFlOTA0YTQ5MTI0OTRiM2QwYWM4N2YyMmFhZjk1ODEyOTc0NDU0OA==
+  - - releasenotes/notes/bug-1687814-743ad8418923d5e3.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bug-1689233-c3f98e159c75374e.yaml
+    - !!binary |
+      YWNjMmQxMDZhYmZiNGZlZDBmZjVkMGQwYzI0NmQ2OWY5ZWExNzU4Yg==
+  - - releasenotes/notes/bug-1696111-e2cf9233fa872eb7.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/bug-1698390-0df8f0ec4fe354de.yaml
+    - !!binary |
+      NzdmZjAxMWNlZDE4MjYwMjQyMjI0YTczMTdhYmE5MmQ1M2ZmMTQ1NQ==
+  - - releasenotes/notes/bug-1698742-66d9d4e6c7ad274a.yaml
+    - !!binary |
+      YmNhOGQ1N2ViMzk2M2JlYjc0YmFhNWQ3NWU2MTk1NGM2MTAzNjlkMA==
+  - - releasenotes/notes/bug-1704097-8ff1ce1444b81b04.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/credential_list_user_type-c809e5b8014d6275.yaml
+    - !!binary |
+      NDcwYTFmMWFjZmUyNjEzNTdmYzMxMjViMmRiM2JjNmVjMTBjNjU0ZQ==
+  - - releasenotes/notes/image_set_visibility-babf4ff2f687d465.yaml
+    - !!binary |
+      MzQ2OGVhMWNhNDI5ZThiNjQwM2FlNWY5ODljZmVkNTIxZDhmNTY5MA==
+  - - releasenotes/notes/object-stdout-db76cc500948b0e8.yaml
+    - !!binary |
+      MWYyMjk1Y2Y2NTMxYjU4OWRlNGY2ZDc4YzVkMTBmMWMzMTUzN2JiNw==
+  - - releasenotes/notes/remove-unsupported-set-vlan-transparent-eeff412264ae7c09.yaml
+    - !!binary |
+      MmI2NmM3MWE3YzI3OThkYzFmOTE0OTU3NGQ1NDA2MmI5MDg2YTAxYQ==
+  - - releasenotes/notes/skip-name-lookups-9f499927173c1eee.yaml
+    - !!binary |
+      MjY4OTk4NGJhNzFmYTBiZTI1ZDIzNjgyNzdmMzNmMmZiNWM0MTI2Ng==
+  version: 3.12.0
+- files:
+  - - releasenotes/notes/bug-1688194-bb008b65267a1169.yaml
+    - !!binary |
+      YzY5MzA0ZTNkMzY1ZGMyYzY3ZmFiMjk4ZWJhMGI5MDk3ZDM4MTlkYQ==
+  version: 3.11.0
+- files:
+  - - releasenotes/notes/add-network-flavor-profile-e7cc5b353c3ed9d9.yaml
+    - !!binary |
+      N2VmMWU5ZWE5NmVmMTViNjMzMDRhNmJjY2FmMzBmOGMyNjlmMmI3Ng==
+  - - releasenotes/notes/add-qos-policy-list-options-9ba1ae731a88e7ac.yaml
+    - !!binary |
+      OWZkM2RiYTExZTVmYzYwMDIzYTljMzMyY2ZiNzZiNDJkMzhhZGYwNQ==
+  - - releasenotes/notes/add-quota-list-command-0d865fac61db2430.yaml
+    - !!binary |
+      NTg1OTFkM2MzN2MwMjY1ZDg3NzVmODgxMjcxYmE0ZDk4N2U1ZmZiNg==
+  - - releasenotes/notes/allow-to-add-remove-vm-ports-273593d7cc1982de.yaml
+    - !!binary |
+      MjE1MTBhYzFhOTRlZWI4ZGUyMThhMGVkZmU4MWRiNWVmMDQzNzI0OQ==
+  - - releasenotes/notes/allow-to-create-legacy-router-cb4dcb44dde74684.yaml
+    - !!binary |
+      NTNiYTA1MzI1YWQ1ZTU4MGU2MmFkZGI3ZjRiNDA1Yjk2YWQwMWQ4MA==
+  - - releasenotes/notes/allow-to-specify-vm-ip-to-publish-85f7207740c0cc8d.yaml
+    - !!binary |
+      ZjU1Mjc4NzdiYjZkYWIwOTc1N2I2NjkyNDYwYmNjMzc2YjdkNWVjMw==
+  - - releasenotes/notes/allow-to-vm-ip-to-add-7721ba64b863fa77.yaml
+    - !!binary |
+      N2Y5ODE0ODYwYWQ3MzllMjViODI4OTgxNzZkMjZjN2I3ODhlOGUzMw==
+  - - releasenotes/notes/bp-extension-show-6f7e31a27dad0dc9.yaml
+    - !!binary |
+      OTkxNWVmZGQwYWJlYmQ5MWEzZjA1YTI0MmUwZTIwYmJkNWQ1ZWZhOQ==
+  - - releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml
+    - !!binary |
+      ZjRmZDhmNmUzMWRjYzE3N2I1NmQxZTYxOGNkZWZlZjcyOGQwOTE1Nw==
+  - - releasenotes/notes/bp-support-multi-add-remove-9516f72cfacea11a.yaml
+    - !!binary |
+      ZWY1YTdjYWY4NWJkNjE2OTcwMTM3MWRhNjcwMjk0NTdhYmRhZjQ3Zg==
+  - - releasenotes/notes/bug-1549410-8df3a4b12fe13ffa.yaml
+    - !!binary |
+      ZGVlMjJkOGZhYTBjOGEwZGExZDZmZjYyYzA5OTdjMmNjNzcwYjc1OQ==
+  - - releasenotes/notes/bug-1596818-d4cd93dd4d38d3d6.yaml
+    - !!binary |
+      NmMxYjAzYmY3MzU0ZmUzOWQ2MWJiOWNmOTNkMjQ5MWJiYjVlYmIxNg==
+  - - releasenotes/notes/bug-1612136-ec240349a933db12.yaml
+    - !!binary |
+      NWZmMmNmZDA0MmRlN2FmYzQzMjNhM2IzMDZmZjViZTE4ODJmYmE0Ng==
+  - - releasenotes/notes/bug-1612898-bea3b68251d12d81.yaml
+    - !!binary |
+      ODU0OTA3MTM2MzgwNWE5ZWVmODE1ZGQyNDI5YjZiODYwZGIxMWEyYw==
+  - - releasenotes/notes/bug-1627555-3b47eba215e35b3c.yaml
+    - !!binary |
+      NDlmNjAzMmI2OTk4MDRiMWIwZWQ1NjEzN2FiMTRiYTI2NjI1MTE1Nw==
+  - - releasenotes/notes/bug-1633582-df2bee534c2da7fc.yaml
+    - !!binary |
+      OTkxNWVmZGQwYWJlYmQ5MWEzZjA1YTI0MmUwZTIwYmJkNWQ1ZWZhOQ==
+  - - releasenotes/notes/bug-1642030-166b2b28c8adf22e.yaml
+    - !!binary |
+      OTkxNWVmZGQwYWJlYmQ5MWEzZjA1YTI0MmUwZTIwYmJkNWQ1ZWZhOQ==
+  - - releasenotes/notes/bug-1659894-4518b10615498ba9.yaml
+    - !!binary |
+      MWM0OWExZjAxZGE3M2I4ZWVkNzAxODA5ZGU4OGI0MDhlNzM4ZGZlZA==
+  - - releasenotes/notes/bug-1659967-644a8ee3621c9e81.yaml
+    - !!binary |
+      ODg4MDIyZjhjMGEyOTExYTAzZmM2ODJmZGJlNGM2OGMzNWEyN2RiNw==
+  - - releasenotes/notes/bug-1664255-f82c5c13d92fed2a.yaml
+    - !!binary |
+      ZmU1OWUzMzlhZTZkZDZhNWU5MDc1NzczZmI1YzJhMGZlYTljMmU1Mw==
+  - - releasenotes/notes/bug-1670707-c4799fbed39ef75b.yaml
+    - !!binary |
+      ZjEzNDVkYzA2ZjkxMTc3Y2VkMTdmMTAyYmNkYWFhMTI2ZmUxMjU2OA==
+  - - releasenotes/notes/bug-1672634-ef754cb5109dd0f2.yaml
+    - !!binary |
+      ODUzZWE1YWI1OWU1ZDc4NDVkMzg5ZTQ2NTI3MDM4NTc1YzNjMTcwYw==
+  - - releasenotes/notes/bug-1677236-7de9d11c3f0fb5ed.yaml
+    - !!binary |
+      NjFjZGU5YzhlODUxODIwNzNiNTNlMzczNmY4NTY4ZjJhNmQxNDUzYw==
+  - - releasenotes/notes/floating-ip-set-unset-port-28e33875937b69cf.yaml
+    - !!binary |
+      NzYzYzhjNTY3MGYyMzg5MjAzOTgxNjVlNjcwNTkyZTAwNjIxM2YzMg==
+  - - releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml
+    - !!binary |
+      YjUxMzEwYTRiYjU5OTcxMzdhNGI2YzBjZjM1MTdmNDgxZTE3ODQ3NA==
+  version: 3.10.0
+- files:
+  - - releasenotes/notes/add-network-auto-allocated-topology-481580f48840bfc4.yaml
+    - !!binary |
+      MTE2OTQzNGY0MmE3NTFjYTllZjM3ZmVkMmZhMmZkMDRmZThiNmY4Yg==
+  - - releasenotes/notes/add-no-property-f97e4b2f390cec06.yaml
+    - !!binary |
+      MWU3MzlkN2FlYmU1M2QzODAzOGI5ZjYxNzJlYjA4OTE2YTdkZDIzYw==
+  - - releasenotes/notes/add-volume-host-failover-8fc77b24533b7fed.yaml
+    - !!binary |
+      NTUxOTVjZWM0NmZhZGQ4OGY2MTUxNzgzYjFlMTc1NTdkNWU5NDk0MA==
+  - - releasenotes/notes/bug-1499657-eeb260849febacf3.yaml
+    - !!binary |
+      MjA0MjliZDVjNjI0Mzk5NTc4Y2I3MjE3ZTU4MmViODYwNjgxMTRjNg==
+  - - releasenotes/notes/bug-1634799-1322227c9b0188ca.yaml
+    - !!binary |
+      ZTBlNDZiY2EwOTM5ODQ5MjZkZTExNTU5ZTMxMmQxZjFmY2FkZTEwOA==
+  - - releasenotes/notes/bug-1651117-a1df37e7ea939ba4.yaml
+    - !!binary |
+      YjJmZDhiYTg2OWNkNGI4ZTkyNzExOGY3NzEyZDBlZDdmYjYwMzA5Zg==
+  - - releasenotes/notes/bug-1656788-2f5bda2205bc0329.yaml
+    - !!binary |
+      OWQ5NDZmMGY0NWM4M2M1Njc3ZTlkZDI2ODg4MzBjNDVjYjZhMjRhZg==
+  - - releasenotes/notes/bug-1658614-f84a8cece6f2ef8c.yaml
+    - !!binary |
+      ZThiNmE5ZjdiZTdlNzczMzk2YzhmZTEwMjFkODc5OGFhMGUyYTRhOQ==
+  - - releasenotes/notes/bug-1661814-1692e68a1d2d9770.yaml
+    - !!binary |
+      M2FmZDJiN2ZmMjVhZjdlNzk5OGU5YzhmNGFkYWM4YTU4YTA3OTY3NQ==
+  - - releasenotes/notes/bug-1663520-d880bfa51ca7b798.yaml
+    - !!binary |
+      YzA1MWM1ZjA5MGZhNjcyOWEwMDVjOWQ0NjJhZmQ4YTc1ZmMxYjQwZg==
+  - - releasenotes/notes/bug-1665231-3df6d090d137fe4f.yaml
+    - !!binary |
+      N2Q5M2RiMjFlNTllODUxOGVkMmNhODAxOGNlY2I2OWRjM2Y1YjJlNA==
+  - - releasenotes/notes/bug-1666780-c10010e9061689d3.yaml
+    - !!binary |
+      MjA0MjliZDVjNjI0Mzk5NTc4Y2I3MjE3ZTU4MmViODYwNjgxMTRjNg==
+  - - releasenotes/notes/bug-1667699-6dad786b128ca8b5.yaml
+    - !!binary |
+      MjA0MjliZDVjNjI0Mzk5NTc4Y2I3MjE3ZTU4MmViODYwNjgxMTRjNg==
+  - - releasenotes/notes/change-098377fd53cce7a0.yaml
+    - !!binary |
+      NGQ1ZjJjMzkyNTA2OGZlNDk3NDhlMDVhNDdjNWM5YzdlNzk5OWIzYw==
+  - - releasenotes/notes/network-flavor-command-support-afe3a9da962a09bf.yaml
+    - !!binary |
+      MzkwNzM4OTc4NTA1NWU0NTk5OTA3ZGNhMzlhZTJjMmJjMGU3ODQ5Nw==
+  - - releasenotes/notes/support-no-property-in-volume-811e67ff4a199eb6.yaml
+    - !!binary |
+      NDBlYzdhOWM5NmY0Y2U0MDcxZTQ3ZTViZjBjMjQ5YWE3N2I1YjJlZQ==
+  version: 3.9.0
+- files:
+  - - releasenotes/notes/bug-1751104-compute-api-2.47-4bfa21cfaa13f408.yaml
+    - !!binary |
+      MWM3NTQxOTdiNThhMjhlOWQzMGFlMTU4NTYwYmQ5OTIxZTdhOGU5Yw==
+  - - releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml
+    - !!binary |
+      MzIyODcxM2VhMzAyYTk2MmMxMWViOTZjZTM0OTE4Yjk0NTI4MjA1ZQ==
+  - - releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml
+    - !!binary |
+      ZGVmYTBmNTYyYjhlZmM4ZmM5MTdmMWIxOTVjOTk4ZTJkNjIyNDI2MA==
+  - - releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml
+    - !!binary |
+      NDkyYTZjNDAwMTY5Njg5MTgyYzA3N2RmNTU0M2Y1ZWMxZTQ4MTM2OQ==
+  version: 3.14.3-12
+- files:
+  - - releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml
+    - !!binary |
+      MDEwZGE5MmZmMzcxMTg3M2U0MGMwZjVhMWMyNjIwMTA0MDBiZjUzYg==
+  version: 3.14.3
+- files:
+  - - releasenotes/notes/neutron_mtu-d87e53e2d76f8612.yaml
+    - !!binary |
+      YTNjYWY3YjMzMTcwOWQ3NmZjNmFlYzUyMjJjNjA2ODhmZDYxMTJhOQ==
+  version: 3.14.1
+- files:
+  - - releasenotes/notes/add-device_id-to-port-list-0c658db51ce43c9e.yaml
+    - !!binary |
+      NWZkZDA3MzBjODhiN2EzZjY1YjcyOGMwZWE4N2JiMzRjYmMxZDljNA==
+  - - releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml
+    - !!binary |
+      Y2Y5MWQ3YTJmNDZiNGE4NTQ2MTY5YTQ4MzZjYzY0NDc2ZmNlNDRkOA==
+  - - releasenotes/notes/bug-1741223-7a5c5b6e7f232628.yaml
+    - !!binary |
+      ZWQxYjU5ODQ4ZmQyYTZiN2JlZDc2MThhYjVhYzBkYjAwZTgxMTBkYw==
+  version: 3.14.0
+- files:
+  - - releasenotes/notes/add-implied-role-0cdafb131fbd7453.yaml
+    - !!binary |
+      OGNkM2UyNThjNTAyOWE4ZWZlZGFiNDAwMTlkNmNmZDNlYWMzNzlmNQ==
+  - - releasenotes/notes/add-network-qos-rule-type-show-57a714a1d428726e.yaml
+    - !!binary |
+      MDdmMGM3YWE1NTkyMGQ2NTAzNTEyNGM5ZThiZmU4NDUyMzU2YzgxMQ==
+  - - releasenotes/notes/add-server-add-network-98ede8ff6079eb23.yaml
+    - !!binary |
+      ZTNhZDgyMTY0ZGM1YzUxYjVmM2NiNzViODI2YmMxNWE2Nzc4YjhiMA==
+  - - releasenotes/notes/add-server-remove-network-fb09c53d5b0c0068.yaml
+    - !!binary |
+      ODA5MzU1ODk0ZmFjNzI5MDg4Njk3MzliNzJkNDRlYWQxYzE4MzA3Mg==
+  - - releasenotes/notes/bug-1513894-6d2f05db6e1df744.yaml
+    - !!binary |
+      MDRlZjhhNDFhY2JkNDVlZjAzMjUzMjQwOTM0ZmEwN2VjMTcwZDdmNA==
+  - - releasenotes/notes/bug-1675489-a1d226f2ee911420.yaml
+    - !!binary |
+      ZTdlZjllODU1Njc3MDUxMzgzNDQ2ZTE4ZTM5M2IxZjk2MTU4MzMxYg==
+  - - releasenotes/notes/bug-1703278-5e45a92e43552dec.yaml
+    - !!binary |
+      ZmQyM2ViZmJmMzA4MGI5NmY3ZWY4YmE1MTZiNjRlNjdhMTExOTcxZA==
+  - - releasenotes/notes/bug-1711301-472b577f074edd43.yaml
+    - !!binary |
+      M2E2NzJlYWU3YmUwZGNmNWUyZTk1MWVhOTU4ZDVkMTU3Njk5YzM0MQ==
+  - - releasenotes/notes/bug-1712242-934bbe2f2378f5bd.yaml
+    - !!binary |
+      ODJmNDVkOWJkMjAzYWVlNzc5MTRjMWY5ZTMwMGY3ZGJlZGY2NzNjOA==
+  - - releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml
+    - !!binary |
+      MjU0ZGJmMzI5NGMwZjFlZGM0YTJhNDY5ZjU1NmIzYzRiMzEyM2EwMA==
+  - - releasenotes/notes/bug-1717829-c1de1d777d3abaf9.yaml
+    - !!binary |
+      ZGUyM2FiOGQ3NWZlODljMTY0YjNiMDg0YzUzZjAxYzI1YjkwNDBjYQ==
+  - - releasenotes/notes/bug-1719413-0401d05c91cc9094.yaml
+    - !!binary |
+      ZjZmNWNlMDNjNWI4YTAzMTgwZGIyNGEwMmRkYTViMzBmNDBiNGNlZQ==
+  - - releasenotes/notes/bug-1719499-d67d80b0da0bc30a.yaml
+    - !!binary |
+      NDQ2NDEwOWM3NzU0YTkyODdmNzVlYzJhZjg0Mzk4NzAwZDE0NTBlNg==
+  - - releasenotes/notes/bug-1728525-2c40f0c19adbd0e8.yaml
+    - !!binary |
+      OWNhOTliOTkxOTQ3YzViOTMyYTBjOTE2NTkxY2Q3MTU2OGYyYWMxNw==
+  - - releasenotes/notes/bug-1731848-71d0a5fdb1a34a8b.yaml
+    - !!binary |
+      MGY3NDljYWNjMmIwYTc2MjI2YTZhN2FiNzc2OWVjZjE0NzVhMTYwYg==
+  - - releasenotes/notes/bug-1732216-b41bfedebff911e1.yaml
+    - !!binary |
+      MTE2NTI2Mjc1ZDA5NTNmZGE5M2M3ZmY4ZWFjZDg2MzFjNWFmNjhkNQ==
+  - - releasenotes/notes/bug-1732938-e4d91732ef777f9a.yaml
+    - !!binary |
+      M2E2NzJlYWU3YmUwZGNmNWUyZTk1MWVhOTU4ZDVkMTU3Njk5YzM0MQ==
+  - - releasenotes/notes/bug-1735836-9be6d777a6e6410b.yaml
+    - !!binary |
+      ZGFiNDlkZjQ2MWQ3Y2E2ODAwMTYzMmYxMWRjNWJmMTIyOTI3MWRlOQ==
+  - - releasenotes/notes/keystone-endpoint-filter-e930a7b72276fa2c.yaml
+    - !!binary |
+      MTJlZTE4NjEwODUxNDRmNDNlNmU1MzVmODJiYTVkOWI1ZDlhNTYzMg==
+  - - releasenotes/notes/support-icmp-type-code-zero-cbef0a36db2b8123.yaml
+    - !!binary |
+      MjIxYjcwNTJhYmNlZmE1NjIxM2E2NTE2Y2VjYzZkZTljNzMwMjZkMQ==
+  version: 3.13.0
+- files:
+  - - releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml
+    - !!binary |
+      NDdmMDI3NzIwODM2MmEzMjI0ZjhlNTg3YmJkZDYwZGQ1YWViZjg0Ng==
+  - - releasenotes/notes/network_dns_integration-5914b2c2be474a41.yaml
+    - !!binary |
+      ZTdhODY4N2EyYzg3YTUwN2NlMjVlMDQyMDE0ZDZhOTE4ZTk1ZDAzNQ==
+  version: 3.16.3-4
+- files:
+  - - releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml
+    - !!binary |
+      YmI3ZjQ5MTY4NTYzNDE0ZDY1YjQwNTBlODRhOGQxZDQ5MTUyMDZiYw==
+  - - releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml
+    - !!binary |
+      ZGRhMDA3YmEzM2I1YzdkMWFlNTM5OTI2YjgyNjc0OTcyNzI3NmUzYw==
+  - - releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml
+    - !!binary |
+      ZmM1ZjI5NzhjMGY0ZjFlMzM2MDMyNWIwMGMxZjFiOTlmMWU2MzE4Zg==
+  version: 3.16.3
+- files:
+  - - releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml
+    - !!binary |
+      ZTA5YzM1OGU3YjM1YWM5Mzg1OTVhYWQ5MGM1YzQyZGZlNDAyYTQyYQ==
+  version: 3.16.2
+- files:
+  - - releasenotes/notes/add-community-option-to-image-list-ac0651eb2e5d632f.yaml
+    - !!binary |
+      ODYwNjM5YTU0OGEyYzA3MTkzNjYyY2QzNjE0MzJjYjUwNjFjMmE3Zg==
+  - - releasenotes/notes/add-image-member-list-1630ead5988348c2.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/add-image-tag-filter-support-5cb039416b07caab.yaml
+    - !!binary |
+      OWVkYmFiOGM5MGJiNzRiYTEyODkyZDBjNzdjOGU4YTk5ZDQ4NjhmZQ==
+  - - releasenotes/notes/add-server-create-image-property-ef76af26233b472b.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/allow-port-list-with-ip-address-substr-14c5805b241e402f.yaml
+    - !!binary |
+      NGE5Y2I4ZWVhOGU0Nzk1MGNiMzBlY2FhNzU3MmEyM2Q4MGQ1YmZjZA==
+  - - releasenotes/notes/bp-unified-limits-58f166401534a4ff.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/bp-unified-limits-6c5fdb1c26805d86.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/bug-1742453-ae4be6de90a3ae1d.yaml
+    - !!binary |
+      YzYxNWJjZDc1ZTg1YTJhMjIzMWQ5OTQ0Y2FlZmZkNzQ2ZTg4MWU1ZQ==
+  - - releasenotes/notes/bug-1750983-420945d6c0afb509.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/bug-1750985-a5345f715a14825c.yaml
+    - !!binary |
+      MDlhMDkxNmRhZWViOWMyNTdkODQxNzVhNDMwNjJkNWI0YTFkMGIxYQ==
+  - - releasenotes/notes/bug-1751104-compute-api-2.47-4bfa21cfaa13f408.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/flavor-add-description-b618abd4a7fb6545.yaml
+    - !!binary |
+      N2U4YzU1ZmExYmJjNWY0NGI5MjMzNjAyNzg2YzIyZDYwMTllZWYyMg==
+  - - releasenotes/notes/implement-system-scope-4c3c47996f98deac.yaml
+    - !!binary |
+      NDIzNmQ3NzdmZmI2ZjAzYmIyNjgyMTQyYWFhMThiNDhlOWEwMGQ5Ng==
+  - - releasenotes/notes/remove-ip-floating-commands-d5363f313e09249a.yaml
+    - !!binary |
+      ZWE4OTA2NWRhYmY5MmMyNjg0ZTU1YzRiMzdjN2JlOWI2NjdjZmExZQ==
+  - - releasenotes/notes/subnet-set-segment-id-4440e433b170f9f3.yaml
+    - !!binary |
+      ZThjNzMxNTQ3ZDg1YjEyNDFjNzg5OGQyZmI3N2I4ZDYzNTkwMWRmZA==
+  - - releasenotes/notes/versions-show-12a2443624c83048.yaml
+    - !!binary |
+      OWVjZTYzMmY5Njg0NGZkNzhjMmY3MTdmMmY2ZDM1ZTYxYzNiOWVmMg==
+  version: 3.16.0
+- files:
+  - - releasenotes/notes/bp-application-credential-a7031a043efc4a25.yaml
+    - !!binary |
+      Mzc1OTY0ZjI3MGUxMjViODg4N2UwY2E0ZWUxY2JlMTVkNWVkZGYwNA==
+  - - releasenotes/notes/bp-project-tags-b544aef9672d415b.yaml
+    - !!binary |
+      ZDMyNjY0MTUwZmJjMDAzNDBmM2ZmNDMwNGMxM2FiZjlhMTkxMjk5YQ==
+  - - releasenotes/notes/bug-1714878-46806jv2yv13q054.yaml
+    - !!binary |
+      NGE5ZTg0YmU5OTQ1NzUxNDZiMzBiZDQwYTM0MWQ1Njg2MTc0ZWFhZA==
+  - - releasenotes/notes/keystone-endpoint-group-0c55debbb66844f2.yaml
+    - !!binary |
+      MWVhZTMwMWM0ZmFiMzBjNTUxZWQ3NTQyY2RhZjg3MzVjYmJjMzgyMg==
+  - - releasenotes/notes/neutron_mtu-d87e53e2d76f8612.yaml
+    - !!binary |
+      MTg1NjNiNDEzMmY3OTRjYzY2MTJjMjg5Nzc5NWY5NmEzMWI1NjVhZQ==
+  version: 3.15.0
+- files:
+  - - releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml
+    - !!binary |
+      MjllYzhjODEzNDA3MmI5YjNlYjZmZjg5MzIwNTA2YmVmOWVjMzU4YQ==
+  - - releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml
+    - !!binary |
+      M2I0OGVmNTRjOGFkMjA1ZGQwODY1MjBjYzE3ZTRmOTY1ODNlODhlYw==
+  version: 3.18.1-3
+- files:
+  - - releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml
+    - !!binary |
+      ZmQzYTk0ZDE2YmU4ZTc4MDZmZjRmM2FhNzQxN2Q4YTBkMzYzNzVmYg==
+  - - releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml
+    - !!binary |
+      MTAwZDM0YzU0ZWNkZmVkZjZmYjQwYTI2ODZlMWFhZTFmNTRkZjk3ZQ==
+  version: 3.18.1
+- files:
+  - - releasenotes/notes/add-member-status-filter-2e118b2c93151223.yaml
+    - !!binary |
+      NDQ0YTQwYzY1NmI5ZjYwMDczNjRlY2QzYmNmMzg5NjRiYmNkNDU1Ng==
+  - - releasenotes/notes/bp-handling-down-cell-ab8af2897f1a8c85.yaml
+    - !!binary |
+      MjM5YjEwMzg0OWI5NjIxM2RjOWNiMzE3MDA2MzQ2Y2UzMTEyMjhlNA==
+  - - releasenotes/notes/bp-network-segment-range-management-0abf03fe03eea149.yaml
+    - !!binary |
+      ZDUyOTIwYjM4Nzg0NzlmN2RkNTQ5Y2JhMTY3OTg3MGI0ZjAwZWUzMw==
+  - - releasenotes/notes/bug-1745699-afa7318b9dc96696.yaml
+    - !!binary |
+      ZTc3NmE0ZjAyNjBhZjFkMmFlNjY0MzllNjQ3Nzk0Mzk1ZDQ3MDU3OA==
+  - - releasenotes/notes/bug-1777153-750e6044aa28d5d8.yaml
+    - !!binary |
+      MDMwZmQ3MTM5MGU4ZTRiODQxM2U5MTZlNjQwNzYzMzcwMzVmOWFhNw==
+  - - releasenotes/notes/floating-ip-multi-port-9779e88f590cae23.yaml
+    - !!binary |
+      MDEzYzlhNGYzYTQ0Y2IwYjgxZmM3YWZmZTliOTMzZTcwMWNiNWRiYQ==
+  - - releasenotes/notes/floatingip_dns_integration-f26c7575694d098d.yaml
+    - !!binary |
+      ZWQwOWYyOGE5ZGQxY2JjMGY4YzE0MWE4ZTM4NTg3YjcwMjJkNDE2Ng==
+  - - releasenotes/notes/image-list-filter-multiple-properties-03c51d43131ee3b6.yaml
+    - !!binary |
+      MjFlNGM4N2JkZWI3OGVmNWM1YTI1MWFlOWU2NzFlZmQxYjVlMzEwMg==
+  - - releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml
+    - !!binary |
+      NzVjYmE5ZDFjYmRkN2IxNGIwZDUwN2FmMjdmODk2YzZjNDVlNzEzZQ==
+  - - releasenotes/notes/name-lookup-one-by-one-e0f15f4eab329b19.yaml
+    - !!binary |
+      ZTc4MmY0OTkyN2E2YjE0MmEzNWY4NWExYTRhNzU5ZmQyYjFjZWVkZg==
+  - - releasenotes/notes/network_dns_integration-5914b2c2be474a41.yaml
+    - !!binary |
+      Yjg3NTRlMTVlN2FkYzlhMDQ1ODdmNjdjODNmZWJhZjQ5YjY0ZjE4Yw==
+  - - releasenotes/notes/osc-included-image-signing-a7021a4dbdcf6336.yaml
+    - !!binary |
+      MTk4MWViMjI1MDBiN2MzODliZWZjOGU5MWQ3YmE1Y2ViYmUxOWE4OA==
+  - - releasenotes/notes/router-gateway-IP-QoS-c8ba95e180bca05f.yaml
+    - !!binary |
+      ZmQyMzAyNTIyN2EwN2U4NzllMGIyOWM2NzA2MzQwMWIxZDM5MjUxOA==
+  - - releasenotes/notes/server-rebuild-property-e8c6439b04e27c80.yaml
+    - !!binary |
+      ZTNkYzMwZmU4YzFhZTZhMTM5MjZiZjFlYWU1MjA5N2U4YmIzN2FhYg==
+  - - releasenotes/notes/server-rebuild-with-keypair-name-83c1aa20db136d91.yaml
+    - !!binary |
+      ZjgyYzViODVjZTlkNmZlZTYyNTUwMDQ0ZmJhYmU1NDE1NWU0YjM2Nw==
+  - - releasenotes/notes/support-uplink_status_propagation-4d37452bcf03e0f8.yaml
+    - !!binary |
+      YzgyZjQyMzdlNTlkZDYxZjE4MGIyYmZiZDMzODNjNjU0MGNkNmNlZg==
+  - - releasenotes/notes/unlock-volume-a6990fc3bf1f5f67.yaml
+    - !!binary |
+      ZjAwZmZlYmVhNjFmOTRmMjMzNGQxYzE1NzhiYzIzOTg2YmJjZjU4Yw==
+  - - releasenotes/notes/volume-backend-c5faae0b31556a24.yaml
+    - !!binary |
+      ZTA2MTVlOGQ2OTE1MmNlMDQxN2Y4NzNiMzAwNTA4MDJhMmRhMGRhOA==
+  version: 3.18.0
+- files:
+  - - releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml
+    - !!binary |
+      YTM2YWMwNTk2Y2RkYWJhZGMyMTU0YjljNzYwMGFiZTJhMjA2NGI5MQ==
+  - - releasenotes/notes/add-parent-list-option-to-projects-10382a7176993366.yaml
+    - !!binary |
+      MDNjMjg1OTVkMTcyYWJlY2YwYWU4OWIzODQ0N2M2N2JjZWRjOTJiNA==
+  - - releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+    - !!binary |
+      NjNlMTVmZjQwNWM0NjgyMWQ2NDY3NjkwMGVkZjAyMDk3M2MyODBkZQ==
+  - - releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml
+    - !!binary |
+      Yjk0OGU3NGI4OGJlZmNhNjdlYWI1NzU3MzQ0NGU4MWY0NGViNzVjOQ==
+  version: 4.0.2-9
+- files:
+  - - releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml
+    - !!binary |
+      MmUwYTBmMTVjZjUwZTIwMDkyNWFlYmQ5NjU5ZDkwM2M3OWI1YjY4ZQ==
+  version: 4.0.2
+- files:
+  - - releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
+    - !!binary |
+      YmZmNTU2YzdjMmUxOWQ2MTYyZmI0NzkyOWI5MWMxNTVlYmEyYTZlZQ==
+  - - releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml
+    - !!binary |
+      YzQyYzI3YWE5MjZlOTNhMjUwN2U2ODZlZWFmMGM1NTEwYTI5ZDI0NQ==
+  version: 4.0.1
+- files:
+  - - releasenotes/notes/add-fip-portforwarding-commands-6e4d8ace698ee308.yaml
+    - !!binary |
+      ZjA0NDAxNmUyOTZmZDI2MWY2MWVkYTY5ZmIyZjVlZjg3ZGU2ZTBhOQ==
+  - - releasenotes/notes/add-host-and-hypervisor-hostname-flag-to-create-server-cb8b39a9f9311d42.yaml
+    - !!binary |
+      MzQwZjI1ZmExNGQ0MjIwNWE0MTM0Y2U0Y2JhNDc3OTI3NjRiODU0Mg==
+  - - releasenotes/notes/add-server-migrate-with-host-4884a71903c5c8a9.yaml
+    - !!binary |
+      Y2IwYzIwYjIzYzU2NGRjNmIyNjA0OTI5MjNhZWY1OGVlNjY2MjBkOQ==
+  - - releasenotes/notes/add-server-resize-confirm-revert-commands-98854ca98965432a.yaml
+    - !!binary |
+      NzU2MWUwNjJlYmQ4MGEyODY1NTUyMzMyMGNiZTFhNDllOTRlZTUwOQ==
+  - - releasenotes/notes/allow-port-create-with-extra-dhcp-options-c2c40e4002b52e2a.yaml
+    - !!binary |
+      Njg4MDlmY2U1YTEwNzM2NTkwMDFhODdhZWU0Zjk0MDdhZmZkNWQwZQ==
+  - - releasenotes/notes/better-ipv6-address-suppport-security-group-rules-95272847349982e5.yaml
+    - !!binary |
+      Y2IwYzIwYjIzYzU2NGRjNmIyNjA0OTI5MjNhZWY1OGVlNjY2MjBkOQ==
+  - - releasenotes/notes/bp-add-locked-reason-425efd2def1144f1.yaml
+    - !!binary |
+      MTg3YmUwYWMyMmJlNWQyZDFjNDJkNDVlOTI5OWU2MmNmYzM3OTZhZQ==
+  - - releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-16e864223d51b50a.yaml
+    - !!binary |
+      ZGQxY2UzNzA0MjQyNjQxNjZiZTY4NjU3OGJjYWIwZmE0MWFjOTczZQ==
+  - - releasenotes/notes/bug-1716789-abfae897b7e61246.yaml
+    - !!binary |
+      Y2IwYzIwYjIzYzU2NGRjNmIyNjA0OTI5MjNhZWY1OGVlNjY2MjBkOQ==
+  - - releasenotes/notes/config-show-00512dc60882e5c0.yaml
+    - !!binary |
+      ODY1ZTE4Mjk3MGM5Y2U0MmQ1YmUwN2NkM2I4MWZiNWRkMWEzZTY1Ng==
+  - - releasenotes/notes/osc4-compute-09246008eff260cb.yaml
+    - !!binary |
+      Yjc3NDJiNTkzNzFiOWUwYjJlNDE3NTQ3ZWIyY2RhYTgwOTU0YjUwZA==
+  - - releasenotes/notes/osc4-identity-6564257c67d43106.yaml
+    - !!binary |
+      ZjlmZGMyOTZiYzZmMmMxZjdkNjE5NjM1MmI3NTRhNzYxN2M0ZjJkMg==
+  - - releasenotes/notes/osc4-image-e922ee6f8e028648.yaml
+    - !!binary |
+      NjdkYWRkYTc0Njc1OWQ4Y2Y0NzgyMmU2ZjQyNmM0NzNlNDZhY2MyNw==
+  - - releasenotes/notes/osc4-network-db2aed696d964ca6.yaml
+    - !!binary |
+      NWEwZmM2OGE4N2QxYzk3MzNjMWRkNWJiNmY2OGIyZTUxOGZlMjEwNQ==
+  - - releasenotes/notes/osc4-volume-470422e5a453310e.yaml
+    - !!binary |
+      ZTc2ZTEwYzBiYWM5Y2Y4N2M1NjRhN2YwMjAxZGYxODlmN2NkOGI1Mg==
+  - - releasenotes/notes/story-2005349-compute-service-set-2.53-3d2db875154e633a.yaml
+    - !!binary |
+      NGJkNTNkYzEwOTBmZGE4NmY2Y2UyNWI3NmEwNzllMjUwYzkyMDZkOA==
+  - - releasenotes/notes/story-2006302-add-boot-from-volume-cd411b1ca776bb3c.yaml
+    - !!binary |
+      YjlkNjMxMDU1NjZjODRkYjExYTk3Njg0Njg0NGFkN2IzYTBiMzMxZQ==
+  - - releasenotes/notes/story-2006302-support-bdm-type-image-0becfb63bd4fb969.yaml
+    - !!binary |
+      NmExOTliZDE0MTUyODg5ZjE4YWQ5NTkxOWE0YmVlOWMwYzA4M2Q1ZA==
+  - - releasenotes/notes/usage-list-all-49ca7a62c50e71d3.yaml
+    - !!binary |
+      MDM3YTgwMDUzOGZlYjY5MGFmMDU0MWQ0ZjI3NmRjZGY0OGFmM2Y3Mg==
+  - - releasenotes/notes/volume-v3-default-0ffa9bebb43b5057.yaml
+    - !!binary |
+      Y2IwYzIwYjIzYzU2NGRjNmIyNjA0OTI5MjNhZWY1OGVlNjY2MjBkOQ==
+  version: 4.0.0
+- files:
+  - - releasenotes/notes/bug-1411190-live-migration-host-655ae6befa6a3de2.yaml
+    - !!binary |
+      MzA1Nzk4OTcxNGU1ZTUxMGUyNzVjNDU0MjU4ZTBmMTY3ZWQ1NTFkMg==
+  - - releasenotes/notes/bug-1740232-91ad72c2ac165f35.yaml
+    - !!binary |
+      NzFmMTM4YjE3MmU5NTUxNWI5ZDU0ZWVlOWIzZTMxOGRmMzM4MTc5MQ==
+  - - releasenotes/notes/bug-1775482-7ed2a9a8765b313e.yaml
+    - !!binary |
+      NDE1YjQ4MDU2ZDlkMDIxZTA0ZWM5NzIwMjkwNDBhODlhNmIxMzkyOA==
+  - - releasenotes/notes/bug-1827844-8f1de120087c6a22.yaml
+    - !!binary |
+      ZWYxZmQzODgxNTRlZWUxMWI5ZTgzZjgwZTUwMDQ2NzBmZGZmYjZjYw==
+  - - releasenotes/notes/bug-2005521-0274fc26bd9b3842.yaml
+    - !!binary |
+      MDRlMDNiMmExZmUzNDA0NmUyMTQ4ZDNjMWQxN2I5MDUzMDEwYzhhZg==
+  - - releasenotes/notes/bug-27882-402ced7ffe930058.yaml
+    - !!binary |
+      NmYxZjQ0ZDQyMmVkM2YzODRlYTZkNGQ3MjkyMjcyNzdmMDk4OGI5OQ==
+  - - releasenotes/notes/rbac-add-security-group-35370701a06ac906.yaml
+    - !!binary |
+      YmU3YTc1ODE0Y2E0YTUwM2RkMzg0ZjM2MTY2ZjkzZjEyZjZjYjhkYQ==
+  - - releasenotes/notes/server-description-ae9618fc09544cac.yaml
+    - !!binary |
+      Yzc3YTk2MjFiZWFmNzc0OGU1Y2NmZWNiM2FjMzdmYTk2MDJjNWJmZQ==
+  version: 3.19.0
+- files:
+  - - releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml
+    - !!binary |
+      ZjBkMjEyMzdhMmRlM2QxMWNhNjhmZWUzMjFkZDBmOGE3MjRlMTg3MQ==
+  - - releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+    - !!binary |
+      MGE2YmFiYzA0Y2U1M2E5MjM0NTIxZTA1NDliYTExYjcyNWQyMGJmNw==
+  - - releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml
+    - !!binary |
+      NjQzYjY5ZDkxNDgwZTQ2MWZmMzU0NjMxODk0MzUxN2IzMjI2ZDExYQ==
+  - - releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml
+    - !!binary |
+      ODliNGE2ODlmYzljNGI5N2I2NDc2MzZlZjZkYjk2MjY4MzM1OTU0Zg==
+  version: 5.2.2-8
+- files:
+  - - releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml
+    - !!binary |
+      YjMwODQzY2VlMzVlNTBlNTE2YTQxYTQ4YmNiZTAwZGQyYzE2MzlmNA==
+  - - releasenotes/notes/task-40279-eb0d718ac1959c50.yaml
+    - !!binary |
+      NWIyNWVhODk5ZTAyM2JjZDNkNzM4NGNjYTk0M2Y5ODQ0YmNiMGI3OQ==
+  version: 5.2.2
+- files:
+  - - releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
+    - !!binary |
+      MTk3MjNhZWUxOGUyOTAxZTkyNTBkZDg0MGE2MTM1OTcwNGJhYTE3MA==
+  version: 5.2.1
+- files:
+  - - releasenotes/notes/complete_image_switch-203e0b3105a54674.yaml
+    - !!binary |
+      NzY4YTY0YWFjNWJkMTRmNTZjMTQyZmFlZWMxNzkzYWFjOTE5NDdjYg==
+  - - releasenotes/notes/use_sdk_for_image-f49d2df38e7d9f81.yaml
+    - !!binary |
+      NjBlN2M1MWRmNGNmMDYxZWJiYjQzNWE5NTlhZDYzYzdkM2EyOTZiZg==
+  version: 5.2.0
+- files:
+  - - releasenotes/notes/add-description-to-role-afe7b6ff668df261.yaml
+    - !!binary |
+      ZWIwMDE3MzNmZDNjMWE5ODAyN2Y3NDM5Yjg0ZTk1MmYxZWIyYTQwNg==
+  - - releasenotes/notes/bug-1784879-9b632174d4af853f.yaml
+    - !!binary |
+      NjhhYTM1ZjM1ZjIxNDc2MDg1ZTI1YWQyZTNkYTUxYTE5NjE5NDhlNA==
+  - - releasenotes/notes/disallow-setting-default-on-internal-network-824fdea1a900891c.yaml
+    - !!binary |
+      OTYyZWZkOTQ5ZmViNDYxMjgzYTliYjRhNjY4ZmJkMzEwZjgwYmE0MA==
+  version: 5.1.0
+- files:
+  - - releasenotes/notes/add-parent-list-option-to-projects-10382a7176993366.yaml
+    - !!binary |
+      N2MxYjZhNzk5ZTBhYzZmZWE1MTFhMmNmMWU5N2FlYmIyZjk0ZTBkNg==
+  - - releasenotes/notes/add-server-migrate-confirm-revert-commands-9d8079c9fddea36d.yaml
+    - !!binary |
+      NjA5OTg4ZWJhYzJjNmJiYjU5NmFhNzdiNDY1ODkyNzRmZmJjMWUwNw==
+  - - releasenotes/notes/bp-support-specifying-az-when-restore-shelved-server-9179045f04815bbb.yaml
+    - !!binary |
+      ODc0YTcyNmY1MjJkYWUzYTA4ODMyZjMyMjMwZTI1OTBhNzg3ZDQ1Yw==
+  - - releasenotes/notes/bp-whitelist-extension-for-app-creds-9afd5009b374190b.yaml
+    - !!binary |
+      NzBhYjNmOWRkNTZhNjM4Y2RmZjUxNmNhODViYWE1ZWJkNjRjODg4Yg==
+  - - releasenotes/notes/bug-2006761-9041d1b25e845cfb.yaml
+    - !!binary |
+      ZjUzODRhZTE2YTI0Y2RkNTQxNDlmYTIxODI3ZDE0YjhiODk4M2Q0Zg==
+  - - releasenotes/notes/drop-py2-421c90fbdf18dbc2.yaml
+    - !!binary |
+      ZTZlNGI3M2VmYTAxMjgxMDAyOTMwZTA4MDZiNzY1MjAwZjM4ZTdjOA==
+  version: 5.0.0
+- files:
+  - - releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml
+    - !!binary |
+      NzY4ZGNhNWE2OTVkNzhkOGM1YzIyZmNhMTg1MTM3ZDNjNWI4YzA3Yw==
+  - - releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+    - !!binary |
+      ZmVmNDczMzkwYzdiYjY4NzRhMzhiOTgwNTNlNTRjZjE4NTQ3YjIzYw==
+  - - releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml
+    - !!binary |
+      OGRiZjE0MWQ1MmM4NGQwYTczMTFlNjJkMzlkMjI5ZmRjODA4NzZmZA==
+  - - releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml
+    - !!binary |
+      ZGQwNmE0YzQ3NWExODEzZGM3MmJmNDM5YmZkY2I0N2RlZWM4OTA0OQ==
+  - - releasenotes/notes/story-2007727-69b705c561309742.yaml
+    - !!binary |
+      NWE3ODQxZDVmMDRhNzZmNmFiMmFkMDFkNmI0MWUwMTAzOGViZDJhOQ==
+  version: 5.4.0-14
+- files:
+  - - releasenotes/notes/add-port-numa-affinity-policy-4706b0f9485a5d4d.yaml
+    - !!binary |
+      NDU0YjIxOTU2NDlhZWMxYTllYjFmZGFhNjBiNjQ2NjNjYjFmNzI5OA==
+  - - releasenotes/notes/bug-2006635-3110f7a87a186e62.yaml
+    - !!binary |
+      ZTI0NjczMjY3MDkzZGU4NWJlZWU3NTM4NjBjZGExZmIyMjRjZTRiYw==
+  - - releasenotes/notes/properties-with-image-property-field.yaml-c51bf37c3106d6ff.yaml
+    - !!binary |
+      ZmJkMmMwMGI4OTk5MjAyOTE3NjcxYmNkYjM5Mjk4ZWIzOWMzYWQ0Nw==
+  - - releasenotes/notes/security-grp-json-fix.yaml-2af1f48a48034d64.yaml
+    - !!binary |
+      YmFlODliMzAxNDRmZGY0MGQwZmVhMzFlMWE1OTViNTA3ZTMyYzRmMw==
+  version: 5.4.0
+- files:
+  - - releasenotes/notes/entrypoint-3.8-0597d159889042f7.yaml
+    - !!binary |
+      ODJlYmRkY2EwMDZkMWRjNjE4NTVmZGQzNGIwNjE2MjIyMDM5ZWE1OA==
+  version: 5.3.1
+- files:
+  - - releasenotes/notes/add-description-field-in-port-forwarding-c536e077b243d517.yaml
+    - !!binary |
+      NzRhN2MxZDlkNmVmYzU0NTY3NmNlYzFkOWVmZWIyYTg2YzViYzU0OA==
+  - - releasenotes/notes/add-image-import-flag-899869dc5a92aea7.yaml
+    - !!binary |
+      YzA0ZWMxNmNmN2FkMmRiZTdiZjhlZGY1ZjZlNzg0MGM1NGIwZWZhMw==
+  - - releasenotes/notes/add_options_to_user_create_and_set-302401520f36d153.yaml
+    - !!binary |
+      MDVkYTE0NWVhZWUzMjllMjk5YjQ0OWJhMmQ3ZWE4OGQxMzI1ZTQzMg==
+  - - releasenotes/notes/add_resource_option_immutable-efed6e1ebdc69591.yaml
+    - !!binary |
+      N2Y2NjI3M2QzZjJmYjY0NDlkN2I1MGQ4ODQ2MGFjZTBjYjgxYmYzMA==
+  - - releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
+    - !!binary |
+      NTMzYWY5ZjFiMmRlNDBkOThmNjllODNjZGY4OWVjZjI1NGNmMzg3OQ==
+  - - releasenotes/notes/fix-story-2007890-0974f3e69f26801e.yaml
+    - !!binary |
+      YzA2ZDgyNTYzNTI2YzcxNWQzZWQ1MDhmYTNjYzVmOWRjMDk2MzI5NA==
+  - - releasenotes/notes/force-flag-openstackclient-c172de2717e5cfac.yaml
+    - !!binary |
+      YjMyOGNmNzRkZjdmOTRhMjBkZTg1YjNjMDk5MmRjYjY1ZTgxODQ1OA==
+  - - releasenotes/notes/rbac-add-address-scope-7f6409ab70d36306.yaml
+    - !!binary |
+      ZjAzY2I2OGFkODlkY2M4NTZmZGFkMWE0NmZlZTM2YjdkNjhjNWJhMg==
+  - - releasenotes/notes/rbac-add-subnetpool-f1fc0e728ff61654.yaml
+    - !!binary |
+      NTU3ZTY1ZDhlYmFmN2VhZWNiMmY5MzhkNjVmZWZmYTBlOTdhODZkNA==
+  - - releasenotes/notes/router-extraroute-atomic-d6d406ffb15695f2.yaml
+    - !!binary |
+      ZGJhNTdjODVkNTUzNjM2OWQ2MDBhZTk4NTk5YzA4YjkyMTcxM2JkNQ==
+  - - releasenotes/notes/stateful-security-group-a21fa8498e866b90.yaml
+    - !!binary |
+      NWU2MjQxMWU1ZjZjNWI2ODUxMmQxZjcyNDcwYjQyMjIxOTllYjQ1Ng==
+  - - releasenotes/notes/task-40279-eb0d718ac1959c50.yaml
+    - !!binary |
+      YjFmYzU4N2E2ZDRlYWM3OTVhNWJjMjdjMmRmZmQyZDg3NjE2MWNhYQ==
+  version: 5.3.0
+- files:
+  - - releasenotes/notes/bug-1946816-7665858605453578.yaml
+    - !!binary |
+      M2Y0MTQyZDVkZGZjYThjNTk0ZDM1YmIwZTVmZDY1MDA5Mjg2ZDExYg==
+  - - releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+    - !!binary |
+      NGI3ZTc3N2MwY2UxOWFhNjdhOWEzM2NiZWIzYjRlZTJiMDUyMzgzZg==
+  - - releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml
+    - !!binary |
+      OTQyNWU2ZmNiNmI5MDdmYmFlN2UxZWI2YjAxYWQyOTMxOTljZWU3NQ==
+  - - releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+    - !!binary |
+      ZWNhYTI4MDVkY2Y4ZWE3MjcyOWExY2ZlZGIzMGViNjBhNjYyMjRiNA==
+  version: 5.5.1-16
+- files:
+  - - releasenotes/notes/add-image-progress-option-to-create-1ed1881d58ebad4b.yaml
+    - !!binary |
+      NmY2MTZhMjliMzAwMjM4YzAwNGI2NzZlZGQ5OGE1MzM3YmUzODE5Mw==
+  - - releasenotes/notes/add-image-project-filter-support-ed6204391e503adf.yaml
+    - !!binary |
+      M2M4MGIxYjNiMjkzMDczODFiODY5ZjZhNzY3ZTE0ZTlkNDdlMjEyZg==
+  - - releasenotes/notes/add-keypairs-project-filter-99cb6938f247927f.yaml
+    - !!binary |
+      NTY0NWZhZDc2MjJhMThlNGYzYzU1MGVlN2Q0MDliZjFiNjg1YTFhNQ==
+  - - releasenotes/notes/add-keypairs-user-filter-e1ce57a4c09c278b.yaml
+    - !!binary |
+      OThhMDAxNmNmYTFkMzliY2MzNzE0NGYwYzc3MDBlOWE5ZDZiMmMwYg==
+  - - releasenotes/notes/add-missing-hypervisor-list-opts-71da2cc36eac4edd.yaml
+    - !!binary |
+      MjYyZTUyNWFhZGE4YmZhZWRiNDU0NWJlNWQyYmJkMjdlZGNjNTVmZA==
+  - - releasenotes/notes/add-missing-keypair-list-opts-243a33d8276f91b8.yaml
+    - !!binary |
+      ZmMyNDE0MmVkNDFlMTU2MjI2ODc1NThjNjhkNjcwYmRjMzcyMjNmMA==
+  - - releasenotes/notes/add-missing-server-create-opts-d5e32bd743e9e132.yaml
+    - !!binary |
+      YWNlNGJmYjY0MDRiN2IzOWM1OTdjNDg4NGM1NmUyNmE0N2E5NGZjNA==
+  - - releasenotes/notes/add-missing-server-delete-opts-071c3e054e3ce674.yaml
+    - !!binary |
+      OGExNjRiYjA5YzA4MDFjM2ZmZDI0MzFkNDFjM2UyMzIzODhhYjQwNw==
+  - - releasenotes/notes/add-missing-server-group-list-opts-d3c3d98b7f7a56a6.yaml
+    - !!binary |
+      NWVjNGQ0YzcxODhmNDc2NmQyNzBiZTMyZTEyYjY0YjcwOWQyYjgzNQ==
+  - - releasenotes/notes/add-missing-server-group-list-opts-ebcf84bfcea07a4b.yaml
+    - !!binary |
+      N2VkNGY2OGM2OGNiMTdiMDJkZWNlZDIwM2Y5YTQ2MTYwNWE2OGRmZQ==
+  - - releasenotes/notes/add-missing-server-image-create-opts-3c19a7492dc50fd7.yaml
+    - !!binary |
+      OTU4MzQ0NzMzYWE2ZDhhZWE2Y2I4ZDA2Y2M0ZDg3OWZlMWVlNDRhNg==
+  - - releasenotes/notes/add-missing-server-list-opts-c41e97e86ff1e1ca.yaml
+    - !!binary |
+      ZDAxMTJhODAxYTIwYzgxMGQ5MmRmY2RmMWY4ZmI3MWRmM2JkMWQyNg==
+  - - releasenotes/notes/add-missing-server-rebuild-opts-5c75e838d8f0487d.yaml
+    - !!binary |
+      ZjlmZDM2NDJmOGU4YzU5Y2Q1YTgxOWUyNjBkMDU3NWY4ODRhZTE3NA==
+  - - releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml
+    - !!binary |
+      OGEwZjNmYzZhOGIzMDMyOGM1NzViYjVjM2ZjMjFkZGM0ZjUwMGQ5ZA==
+  - - releasenotes/notes/add-project-cleanup-beb08c9df3c95b24.yaml
+    - !!binary |
+      MTE5ZDJmYWUyNTY3Mjg1YjkxNDliMmM3MzdkN2Q0NDUyYjU5Mjg4Yw==
+  - - releasenotes/notes/add-server-evacuate-8359246692cb642f.yaml
+    - !!binary |
+      MDFlYjRlODM5Mzk0ZmU0MzNhOTJhMDZkYWYxNDk5ZmIwMGYyZmU2OQ==
+  - - releasenotes/notes/add-server-migration-show-command-2e3a25e383dc5d70.yaml
+    - !!binary |
+      ZjgwZmUyZDhjZjUwZjg1NjAxZTI4OTVhNWY4Nzg3NjRmYTc3YzE1NA==
+  - - releasenotes/notes/add-server-nic-tagging-support-f77b4247e87771d5.yaml
+    - !!binary |
+      OWVkMzRhYWMwYTE3MmVjZTRjZDg1NjMxOTQ4NjIwOGZjZGJhMDk1ZA==
+  - - releasenotes/notes/add-server-volume-update-89740dca61596dd1.yaml
+    - !!binary |
+      Y2E3ZjIzZDBkMTg3NmRjNTNlZjRkNWVjYmYyYzVmMzY3YWFmZTEzZQ==
+  - - releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml
+    - !!binary |
+      MmIwNzNjMjAzNGFjZGFiYjhkNDA5N2I3ZjJjMDQwOGU1M2ZlMmQ2Mw==
+  - - releasenotes/notes/add-tag-support-server-add-fixed-ip-8de2db58f2a80e85.yaml
+    - !!binary |
+      NzQyYzgwYTgyNTc0ZTVhNjkyOGMzMDU4NDIwNDdiOGI2YjJiMzgwNw==
+  - - releasenotes/notes/add-tag-support-server-add-network-a8590cab5d7babf0.yaml
+    - !!binary |
+      NmYxNjAyMzEyYjAwYmNiYTZlMDRhMzRmN2YwNGFmOWQ2OWNmMmQ5Yw==
+  - - releasenotes/notes/add-tag-support-server-add-port-7e30aa38202d0839.yaml
+    - !!binary |
+      ZjNmYmIxYjY0OGE5NmU1NDFiNTNmOTY5MDRiODVkM2ZkY2UyYWYxMA==
+  - - releasenotes/notes/add-tag-support-server-add-volume-278e79a22dd482f4.yaml
+    - !!binary |
+      MWM3ZmUzYjZiZDYwYWEyMmFlNTI1ZDA0MTg3Mjk1OTBmNjQyOWU5Ng==
+  - - releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml
+    - !!binary |
+      MWUwNTNiYWJmNGQ2NzRhYzMxZDUxZGZiYTA0ODcwNGYzMmI1NThiMw==
+  - - releasenotes/notes/add_name_and_enabled_to_list_domain-6d23f02994b51c67.yaml
+    - !!binary |
+      ODYyOGU1MmRlNzQxMmU1N2UxMzIzOGFkMWJhNzExM2RlYjZhMmUxYg==
+  - - releasenotes/notes/always-show-direction-for-sg-rule-130efc39bf67d79a.yaml
+    - !!binary |
+      ZTQxMGU2MWQyMDRkMDllZWI3YmNmMGEzM2UzODU4ZWY3YjExMGRkMw==
+  - - releasenotes/notes/auto-configure-block-live-migration-437d461c914f8f2f.yaml
+    - !!binary |
+      MmJkZjM0ZGNjM2Y4OTU3ZmY3ODcwOTQ2NzE5N2I1ZmNiNDRlMDdjMw==
+  - - releasenotes/notes/bp-add-user-id-field-to-the-migrations-table-299b99ccb1f12a1f.yaml
+    - !!binary |
+      Yjc3YzI4ZDI5NTRhMmM1ODYxYTNhNmExZGYyOWQ4ZGU0NDhmN2MwOA==
+  - - releasenotes/notes/bp-address-groups-in-sg-rules-b3b7742e4e6f5745.yaml
+    - !!binary |
+      ZTAxZTU5Y2FlYjU2Y2I3YmY0ZjM4NDAzYjgyZDBhMjY1YjE2MzA5OA==
+  - - releasenotes/notes/bp-address-groups-in-sg-rules-e0dc7e889e107799.yaml
+    - !!binary |
+      ZjU3ZTEwYjkwM2ZhNzFkMDJhNmUxMDQ3MTc4MjRkMDA0MTc4YmJmNQ==
+  - - releasenotes/notes/bug-1708570-bb19e1213e887723.yaml
+    - !!binary |
+      ZmQ5YTIzNWRlM2IzNTkyMzY2ODE4YWI3Nzk5ZTczZjZiZTAyOWIxNQ==
+  - - releasenotes/notes/bug-2007489-42e41b14e42128ce.yaml
+    - !!binary |
+      MWMzY2YxMTMzMWE1NzM0NzAwZTFjMzMzYzk4OTI4YWI5MzNjMGU5Mg==
+  - - releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml
+    - !!binary |
+      MDhiMGU1ODU1YmU1ZGMxMmEyZmQwNGM1YzkyMDI3YzhhODVhMGQwMA==
+  - - releasenotes/notes/deprecated-server-create-file-option-80246b13bd3c1b43.yaml
+    - !!binary |
+      NmYzOTY5YTBjOGE2MDgyMzZhNmY3MjU4YWEyMTNjMTJhZjA2MGE5ZA==
+  - - releasenotes/notes/fix-flavor-props-formatting-d21e97745543caa7.yaml
+    - !!binary |
+      YWQzMzY5ZWQxZmRhZDczYjVkNDU3YTQwZGY3ZGY4YWQ1NWViNjljZA==
+  - - releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml
+    - !!binary |
+      NWJkY2Q1OTBlY2FjYmMwYWE4ZGIyY2JhZmEwYWIxYTlmM2MyOGNlMA==
+  - - releasenotes/notes/flavor-list-min-disk-min-ram-65ba35e7acc24134.yaml
+    - !!binary |
+      ZGEwM2JkODBlM2I4M2ZhZjQ2NWYxNDQ2YzQ1NTNjNWQ5N2I1YmFkNQ==
+  - - releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml
+    - !!binary |
+      YmY4MzRmNmQ3NTgyMDA5NjcyZmM2NWFhOTgzZjMxNDY4NGRjNDM4MA==
+  - - releasenotes/notes/keypair-support-type-6f7c32aab3b61f7b.yaml
+    - !!binary |
+      NDg1NWZlZjhiOGYyOTU0MmViZGFmODZhYTVkYTRkYWExZjk3YjA2MA==
+  - - releasenotes/notes/keypair-user-id-db694210695a0ee0.yaml
+    - !!binary |
+      MTdmNjQxZTFjM2FjNThhY2RjMzlkMDY0MzY5Mzk1MTk4ZDI2NTRkMg==
+  - - releasenotes/notes/port-device-profile-4a3bf800da21c778.yaml
+    - !!binary |
+      MGNjODc4ZTViMDUzNzY1YTBkM2MxM2Y1NTg4YmMxNjBiMDVhMzg4Yg==
+  - - releasenotes/notes/rbac-add-address-group-f9bb83238b5a7c1f.yaml
+    - !!binary |
+      ZTg1MDlkODFlZTBiNTQxMDMzNDExZTc0NGY2MzNlNzY5MDczNTMwYg==
+  - - releasenotes/notes/remove-deprecated-server-migrate-live-option-28ec43ee210124dc.yaml
+    - !!binary |
+      NzA0ODBmYTg2MjM2ZjdkZTU4M2M3YjA5OGNjNTNmMGFjZWRmZDkxZA==
+  - - releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml
+    - !!binary |
+      ZTliZDRlZjAwNzE1M2U0ZjJlMmQ2OWYzYmNiOTRlZWY4ZTg5ODNjMg==
+  - - releasenotes/notes/rename-server-migrate-confirm-revert-commands-84fcb937721f5c4a.yaml
+    - !!binary |
+      YTUyYmVhY2FhNmZjYzExZDQ4ZjViNzQyYzczYWEyYzBmODc2MzRjZQ==
+  - - releasenotes/notes/restore-create-image-duplicates-92e06f64038b120c.yaml
+    - !!binary |
+      MTc2NzhjOWJkNmYzZjRjNWI5ZTdiNWNlYjI3YzJiZDEyNDkzZmJhNA==
+  - - releasenotes/notes/server-add-tag-63f9cd01dbd82d1b.yaml
+    - !!binary |
+      MmY3NmJmYTNhNjliNjg2NzQ5MWE2YzVmMGJmM2M3ZTlmNjI3NDNjYQ==
+  - - releasenotes/notes/server-group-create_rule_option-9f84e52f35e7c3ba.yaml
+    - !!binary |
+      YTVjNjQ3MGYyZDc2YWZiOWFjODdkMDVjNDMyNmJlYmY5MjVhNTVkYQ==
+  - - releasenotes/notes/server-list-selectable-fields.yaml-1d5fb4784fa6f232.yaml
+    - !!binary |
+      MzExZjQxMzBkMmM1OTYzODA3NDUzMWZhNTllNjc3ODNjMjU3MWU5MQ==
+  - - releasenotes/notes/server-ops-all-projects-2ce2202cdf617184.yaml
+    - !!binary |
+      MWE2ZGY3MDBiZTI1MDdiY2VjNzYwOTk0ZTY0MDQyZDAzYjA5YWUxNg==
+  - - releasenotes/notes/show-server-topology-microversion-v2_78-3891fc67f767177e.yaml
+    - !!binary |
+      ZjIwMDc5OTg0ODgzMWEwMGYzNTBjMzI0YmI3N2MwMGVmYTUwZGExYw==
+  - - releasenotes/notes/story-2004346-add-floating-ip-with-no-ports-399c5559e1699816.yaml
+    - !!binary |
+      NDE1NTQ1YWI5ZmQ4NDJiZGMxOWI3ZmJmYTYzZTMzMzJkZDYzZmU2Yw==
+  - - releasenotes/notes/story-2005468-server-use-config-drive-9fc68552365cfefa.yaml
+    - !!binary |
+      MTJmMWU1NmViZjJlYTM5OTljNTcyNDY0MTA1MDFjMDlmY2VkMmM0Yw==
+  - - releasenotes/notes/story-2007727-69b705c561309742.yaml
+    - !!binary |
+      YmIxNWIyOTE5MGRmZTc3ZWEwMjE4YTAxZWRjMWY0ODg2OTkzYjE3Nw==
+  - - releasenotes/notes/subnet-unset-gateway-20239d5910e10778.yaml
+    - !!binary |
+      ZWQ3MzFkNmNkOTI1NGVhZTA0N2QxNGNjZDU1MTMyMjI5ZTEzZTdkMQ==
+  - - releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml
+    - !!binary |
+      ZjM2YTM0YjY3NWU2OWE4MTFkNWNkNDhmNmJjZmQ2Y2U3YmRhNmE1YQ==
+  - - releasenotes/notes/switch-console-log-to-sdk-6ee92b7833364d3d.yaml
+    - !!binary |
+      NzRkYjhkZDY1ZDM1YjMyNmQzZmExYzY4MGIwNGE2NjhhM2Y2NmJkYw==
+  - - releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml
+    - !!binary |
+      MGY0ZjQyYjY1MjgxYjliOGI0ZjhmYzNlNThkYThjOWQ4YjY4ZWUwOA==
+  - - releasenotes/notes/switch-keypair-to-sdk-81e28380e66a7f9c.yaml
+    - !!binary |
+      NTEyYmExMTRhMThkOWFlNDllYjNlNmI0MTIzZTkyZGQ4OTZkM2Y0Zg==
+  - - releasenotes/notes/warn-on-disk-overcommit-087ae46f12d74693.yaml
+    - !!binary |
+      ODg2OGM3N2EyMDE3MDNlZGFkZWQ1ZDA2YWExNzM0MjY1NDMxZjc4Ng==
+  version: 5.5.0
+- files:
+  - - releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+    - !!binary |
+      NTYwZjE5Yjg5NDhhY2IxNWJjODUxMGE0YmU2YmRmZTdkMzUzYTlkNg==
+  version: 5.6.2-4
+- files:
+  - - releasenotes/notes/bug-1946816-7665858605453578.yaml
+    - !!binary |
+      Y2JjNjRmOTQ2OTYwMDYyNGU3NDYzMWY0MmNhMjE0NDg3ZTgwMDE1NQ==
+  - - releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+    - !!binary |
+      MDg3M2U3NTgwZWNlYWIwN2MzYmUwODI0ZDJlYTQxNjM0OTFmOGQ2ZQ==
+  - - releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml
+    - !!binary |
+      NjY1ZDkzZmYwNzIxODAxODk2YmYwOGMzY2M0ZjE4OWE1NWRhYWU4MA==
+  version: 5.6.1
+- files:
+  - - releasenotes/notes/L3-conntrack-helper-bd0d9da041747e84.yaml
+    - !!binary |
+      ZmE4YzhkMjZhNzY5NmQxNjliMGI5ZDVhYWY2YjcyM2Q4ZmVlZTA4YQ==
+  - - releasenotes/notes/add-missing-volume-backup-opts-b9246aded87427ce.yaml
+    - !!binary |
+      N2Y2NmRmZTBlM2U4NzIwZTg0NzIxMTQ5NGMxODVkN2Q0OTgzYmE1Yg==
+  - - releasenotes/notes/add-volume-attachment-commands-db2974c6460fa3bc.yaml
+    - !!binary |
+      NmRjOTRlMWZiODU1OTU2NTNkY2RkMjQxODVjOTE0YjlkZjE3NDFkZg==
+  - - releasenotes/notes/add-volume-group-commands-b121d6ec7da9779a.yaml
+    - !!binary |
+      YWY0MDZmMzNlMzhhOGU5YTVmYjNjNThlMzRmMGQ1NWMxZDRkMWQ3NA==
+  - - releasenotes/notes/add-volume-group-snapshot-commands-27fa8920d55f6bdb.yaml
+    - !!binary |
+      MzRkZTJkMzM1MmFhZWY1YzFiYjg2YTU0NDFjYzg3ODFlMDNiNTU4Nw==
+  - - releasenotes/notes/add-volume-group-type-commands-13eabc7664a5c2bc.yaml
+    - !!binary |
+      ODM1NTFkMmEwYzc2MDQxNzljMDk4OGMxM2Q1ODQ1NWE2YjI4OWNjOA==
+  - - releasenotes/notes/add-volume-message-commands-89a590a1549c333e.yaml
+    - !!binary |
+      MGVkZGFiMzZlNTJlODEzZTIzMjlhYzEwMDQ0ZmE0ZjY3ODMwZWZlYw==
+  - - releasenotes/notes/add-volume-transfer-request-create-snapshots-opts-1361416d37021e89.yaml
+    - !!binary |
+      YTgyMWQ2YjdjNTdjNzY4NGE5OTBlZTM5YjZiOTNkNTA4NWYyNWE3MA==
+  - - releasenotes/notes/compute-service-list-forced-down-2b16d1cb44f71a08.yaml
+    - !!binary |
+      MTJjOTNjNmQ1ZmY0MjBmNmE0YTg4MzNkMzNiYWQ2ZWU3MjIyZTJmNw==
+  - - releasenotes/notes/implements-hide-image-4c726a61c336ebaa.yaml
+    - !!binary |
+      MzgzMjg5ZWRkOGVhMjIyY2UxYTZlNzdlZDAyOThlY2RiMjE2MDhhMQ==
+  - - releasenotes/notes/network-port-create-vnic-type-vdpa-fc02516cfb919941.yaml
+    - !!binary |
+      NmY4MjE2NTk3OTVmZGM4MmM2OTRiYjlmZGRkZDVkM2M2MTcwMmUyMQ==
+  version: 5.6.0
+- files:
+  - - releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml
+    - !!binary |
+      ODQ5ZTdlOTNmODNhMjIwMjY1ZDExYWY3MWUyZWRjMDA5YzNmN2JlYQ==
+  - - releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+    - !!binary |
+      ZjQ3NDhmNGQyNTBkNGQ4ZWI1OTJiNzE3MGYxZTAyMGY5ZWNlOGRmMw==
+  version: 5.8.1
+- files:
+  - - releasenotes/notes/add-network-local-ip-df3a9ce7610d8b90.yaml
+    - !!binary |
+      MjYxNDQ3NDNkOTIwN2Q4NzZkZjQwZTAzMGEyYTQxMzJlMThhNzlhNw==
+  - - releasenotes/notes/add-option-to-unset-port-host-c76de9b1d2addf9a.yaml
+    - !!binary |
+      ZjQ2MjkzMzExMzRjNDA1OTlmOWJhZjkwOGEzOTE0NjBiNzRkMjc2Nw==
+  - - releasenotes/notes/add-remote-managed-vnic-type-4fc540b47427c37f.yaml
+    - !!binary |
+      ZDU2NWYxMTA5MzhmNDYyMjRhZGE5MmMzZDY4Y2E0MTZmMDU2MzViNg==
+  - - releasenotes/notes/check-limit-quota-cc7f291dd1b537c1.yaml
+    - !!binary |
+      YmVmNzAzOTdhM2UxMjQwY2M1OTNiM2ZiMzQwNDlmMmZmNjYwMWU2OA==
+  - - releasenotes/notes/fix-flavor-in-server-list-microversion-2.47-af200e9bb4747e2d.yaml
+    - !!binary |
+      OGUzNjI0MDJkZWUwNzc0NDY2OGJjZjdmNjc3NGFmNGZiZTlhMDdlMw==
+  - - releasenotes/notes/list-subnet-by-pool-id-a642efc13d04fa08.yaml
+    - !!binary |
+      ZTRlOWZiNTk0ZDAwM2VhNmMzZWMyOWFhYjBiY2NmNzJmZmFiNjc4MQ==
+  - - releasenotes/notes/migrate-add-fixed-ip-to-sdk-3d932d77633bc765.yaml
+    - !!binary |
+      OTk3MWQ3MjUzZTljM2FiZDJlMzk0MGJmNTQ5ZWY4NTMyZWY5MjlmOQ==
+  - - releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml
+    - !!binary |
+      OWFjYmQzZTEwNTJkNTMzYzEzOTVlYjU5ZGU0Mjc0MTcwYmFlZDY3Yg==
+  - - releasenotes/notes/migrate-server-add-network-add-port-to-sdk-7d81b25f59cfbec9.yaml
+    - !!binary |
+      MjE4M2E2MTE0NzUwOTAzNDc4NjM5MTdmNmM5MGYwZjM4Y2Q4MDg5Mw==
+  - - releasenotes/notes/migrate-server-add-volume-to-sdk-685e036a88839651.yaml
+    - !!binary |
+      MzA3OGEwYTEyMTc0M2MzODdkODNkN2YyN2NlM2Q4ZmQ4ZmJiNGNjZg==
+  - - releasenotes/notes/migrate-server-pause-unpause-to-sdk-d74ec8536b764af6.yaml
+    - !!binary |
+      YjUxNWZlNjFiMjc0MDhlNzg2MzlkYThhYmIzYWNhYTQ4NWViY2E0ZQ==
+  - - releasenotes/notes/migrate-server-suspend-resume-to-sdk-fd1709336607b496.yaml
+    - !!binary |
+      ZmY5NmZlYTAxMjBhYjQzOTY4YTEwMjMwY2U3ODk5YTNjNjUwNGU3NQ==
+  - - releasenotes/notes/migrate-service-list-delete-set-to-sdk-920cbe0d210af565.yaml
+    - !!binary |
+      YjVhMjcxNGI4M2Q0Y2UxOTkxYWFlNzc1MzgxZGNmYjAyZmY1OWU5ZA==
+  - - releasenotes/notes/options-create-router-97910a882b604652.yaml
+    - !!binary |
+      NGU5YjkyOTg0MjlmNWRiNTA1OTg3ODUzZjk4ZDIzODhiNjc0NWIxMw==
+  - - releasenotes/notes/pass_ssh_args-cf26a2ce26ccddaf.yaml
+    - !!binary |
+      M2E5Mjk2MTFjMGVjNWRkOGU3YmYyNDY5Mjk4NGQxZGY4YjlhOTdmOA==
+  - - releasenotes/notes/port-list-security-group-4af5d2e789174ff9.yaml
+    - !!binary |
+      YzhjNGY3NjQ5OGRlMzM4MGM3Y2JmODBjNWRjODAwYTU4OGJlZDY0OQ==
+  - - releasenotes/notes/switch-server-remove-network-port-to-sdk-829ba711e0e198d5.yaml
+    - !!binary |
+      ZjgyYWZjN2YzNzlkYWViZDE5OTRkOTEzM2VmZjgwMWY3OTBjMGQzMg==
+  - - releasenotes/notes/switch-server-remove-volume-to-sdk-47e9befd2672dcdf.yaml
+    - !!binary |
+      ZmFlMjkzZGQ1MjE4Y2Y0ZWEwM2QwYTRjNDRkMTdiOTc5ODdkZWExMg==
+  version: 5.8.0
+- files:
+  - - releasenotes/notes/add-server-hostname-opts-3cb4fd90b5bf47ca.yaml
+    - !!binary |
+      OGU4MzNhM2VkMjY0NjdhMTE5MGJhNjlkOGJhNzE2YTdjZDFjY2NiMw==
+  - - releasenotes/notes/add-trusted-certs-option-server-create-a660488407300f22.yaml
+    - !!binary |
+      MjhhMzc2YmZiMGEzMzA0NzBiMDI4YjZkNTI0NGVlNGM4ZTFmZTg2NA==
+  - - releasenotes/notes/add_attachment_id_to_volume_attachment-cea605585db29e14.yaml
+    - !!binary |
+      NTFlZTE3YTk0ZGNjZDI5NzEwMTcyNTU5M2IyMjNmMDFjNGY5YjkwNg==
+  - - releasenotes/notes/bug-1946816-7665858605453578.yaml
+    - !!binary |
+      NTNkZWJlN2ZlMTk3OGY2NjE3NjhhMjc0MzBmNjQ2YTI4ODk0OGVjYw==
+  - - releasenotes/notes/migrate-server-backup-to-sdk-0f170baf38e98b40.yaml
+    - !!binary |
+      NTdhYWQwMTg4NmZlOWQ5ODIxMDQ5NmE5MmQ1MTdhYTA2N2MwNDlhMQ==
+  - - releasenotes/notes/show-result-for-server-add-volume-f75277ad58e31024.yaml
+    - !!binary |
+      MTYzY2IwMWU0NmZjM2Y5MDYxNTRhNzA0NWZkYmU5MzQyY2Q0NDZjNw==
+  version: 5.7.0
+- files:
+  - - releasenotes/notes/add-reimage-param-to-rebuild-606dd331677b5954.yaml
+    - !!binary |
+      N2Q3MDJiYWYxNzFkYmE5OTQyZGI0NGEzODE0Y2UyYzk1NzViMmZlMg==
+  - - releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+    - !!binary |
+      NDgxNDhlN2ExMTk3YzkyZmViZGIzYWIxZTcyMDg1YzRlYjNkNmJmNw==
+  version: 6.0.1
+- files:
+  - - releasenotes/notes/add-block-storage-cluster-commands-fae8f686582bbbcf.yaml
+    - !!binary |
+      ZDcyN2E2NTAyMzY5YTZhNzI0NGVmMWMwN2MxYzQ4M2RiZTBhOGRhYg==
+  - - releasenotes/notes/add-more-server-list-columns-4e3b87929dd330f7.yaml
+    - !!binary |
+      MTA4MzVhMTg4NjMwMWQzNmVlNzdmMDIyMWI3Yjg3NDc2ZmUzMTJjZg==
+  - - releasenotes/notes/bug-1597189-02a8d8a402725860.yaml
+    - !!binary |
+      ZGU0YTY5YTI5ZmY0NjU3ZDBjM2NkOTVjYTlmMzVmZjI0ZjY1M2I1Zg==
+  - - releasenotes/notes/fix-image-create-from-volume-c573e553161605c4.yaml
+    - !!binary |
+      OWVlYTI4YmE1OWU0NDUyNmI5ZDZmMWFkOWY4MGMzNTUzZDU4NTNlMg==
+  - - releasenotes/notes/image-list-multiple-tags-a394799c7807f031.yaml
+    - !!binary |
+      NWNjNmZjMmI4ODI5NjAzNWY2ODdmNzJkOTJlZmU0YTNjZWE3OGZjNw==
+  - - releasenotes/notes/qos-min-pps-rule-bfe22cea1966c4a0.yaml
+    - !!binary |
+      NmNjYmNkZGU2NDY3MGRhYWFhYzRmNDJmZTYyZWIxODBkZjcwMDkwNQ==
+  - - releasenotes/notes/quota-network-force-920913981b45ba1a.yaml
+    - !!binary |
+      MWM2ZDM5NmJhMzBjMWE5MmE0MTdmNzc4ZDc1MjJlYTQzZTliMmQ0YQ==
+  - - releasenotes/notes/server-list-host-status-1f542a5bc4292a62.yaml
+    - !!binary |
+      OTM1NzhlZjg1YmE1Zjk0ZWM1ZGM4ZmM0YjI5MTdlOTFjNzQxMjFkYQ==
+  - - releasenotes/notes/server-migration-by-uuid-59f8272f63abee5d.yaml
+    - !!binary |
+      Y2ZmZWM0NTE3ZjhiZmJlM2E2ZDZkMTYxMGM1YjMyMTcyNzFhOWE5Zg==
+  - - releasenotes/notes/volume-attachment-create-output-fix-56515b8fcdd260b9.yaml
+    - !!binary |
+      MDQ1ZjJlN2UwNjE4ZmRmMjJjMjYwNjI1ZDY0NTU0MzgyYWZlZmRlMQ==
+  version: 6.0.0
+- files:
+  - - releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+    - !!binary |
+      YTAzZTNkYmY3NWM1NTU2MWJjMzU3NWM1M2RiNDQ1ODY4YmU4N2EzYg==
+  version: 2023.1-eom
+- files:
+  - - releasenotes/notes/add-port-ranges-in-port-forwarding-command-8c6ee05cf625578a.yaml
+    - !!binary |
+      YmNlZDQ4NTJjN2E5Mjk1OWY1NDU3MzYwZGQ5MWViMzk3YWY0ZDI3MA==
+  - - releasenotes/notes/consistency-group-create-opts-aliases-e1c2f1498e9b1d3d.yaml
+    - !!binary |
+      NDEwNjkyNmZhNjU2MjJkYzMzZTczMjI4MzIzOTRhZWRiNDdmOTVhZA==
+  - - releasenotes/notes/deprecate-volume-group-create-positional-arguments-89f6b886c0f1f2b5.yaml
+    - !!binary |
+      MGQ1N2YzZjM2NzE2M2RjNGQzYjU3YWU1NzRhODI1NTYzNDk0ZjEzMw==
+  - - releasenotes/notes/migrate-host-list-show-to-sdk-9b80cd9b4196ab01.yaml
+    - !!binary |
+      ZWNjNmFlZWVkZTY4ZGI2NWNiODg4MzkwZGQ5Mjk5YTRjZmFkNjYzMA==
+  - - releasenotes/notes/migrate-server-volume-list-update-to-sdk-95b1d3063e46f813.yaml
+    - !!binary |
+      MjViNDcxNGYxY2QxMmMyMGZmNzY1M2YwNWRkZGI1NDg2YTAzN2ZjYw==
+  - - releasenotes/notes/rename-server-volume-update-to-server-volume-set-833f1730a9bf6169.yaml
+    - !!binary |
+      ZTA1NzdlN2ViZTM1OWZmMjQxMDIzYjY0MDU1Zjc3N2Y4NTA0ZDNhZg==
+  - - releasenotes/notes/switch-server-migration-show-to-sdk-4adb88a0f1f03f3b.yaml
+    - !!binary |
+      ZDFjMWMzNmFmMTVkOGNmYzQzYjI2YjIzOTMyNGI0OGIwOTI0YjY2ZQ==
+  version: 6.2.0
+- files:
+  - - releasenotes/notes/add-backup-option-to-create-vol-fc36c2c745ebcff5.yaml
+    - !!binary |
+      YmQwNzI3YzRmODk3Mjg5NzIyYmE2Mzk5MzBjOWU5NzljZmVlNTM0YQ==
+  - - releasenotes/notes/add-baremetal-agent-type-7c46365e8d457ac8.yaml
+    - !!binary |
+      YjdkMDE4MzNkMDIyNjAwMDZlNmQ0YzZlMGEwNjU3NDhlY2M4YjkxMw==
+  - - releasenotes/notes/add-block-storage-manage-commands-6ebf029bd7a67bb3.yaml
+    - !!binary |
+      NzNiNGNlODhlYjNlNzE1NjhjZjUzMzBkNmMwYThhNGU5MjI4N2Q4OQ==
+  - - releasenotes/notes/add-create-group-from-src-options-6fcb0c87f617ca91.yaml
+    - !!binary |
+      ZWMwMTI2OGVhOTMxNDE0Mzk1NDJmYjE2MmE2YTEyYmMyYmY1MzNmZQ==
+  - - releasenotes/notes/add-image-metadef-namespace-support-4ba37ec3a1a72185.yaml
+    - !!binary |
+      YTcyNmQ4NGY0YjdjZWM3NjFkM2Q4MjgyNDk5Nzk2OWRmZmJkNDI0OQ==
+  - - releasenotes/notes/add-image-task-commands-50c3643ebfd0421f.yaml
+    - !!binary |
+      YzlkNDQ1ZmM0YmFmMDM2NzkzMTAzYjE1YzllYjI2MzJkYTM2MTBlMA==
+  - - releasenotes/notes/add-missing-trust-list-opts-500fd1e4c14e1504.yaml
+    - !!binary |
+      NjRlNDUyMGIyYTc5YjkwNDZhNzkxZjVlMzcyOWY1Y2JmYzJkM2ZhNQ==
+  - - releasenotes/notes/add-network-rbac-list-tenant-project-filter-1228f2287284e33c.yaml
+    - !!binary |
+      NGQ3ZDdlNjI3ZWI0YmIwMjgyNTFiZDc5OTMwMjZhYWU0NWRiN2Q4Yg==
+  - - releasenotes/notes/add-reimage-param-to-rebuild-606dd331677b5954.yaml
+    - !!binary |
+      NDAyNGJkYjM5MzNkZDc5ZWVjNGJjZjk5YzEzZjNkYmYxN2FkZDQwYg==
+  - - releasenotes/notes/add-vol-service-get-set-log-commands-f9420e5061d994b5.yaml
+    - !!binary |
+      YTllMzA0OWU5Y2U4YTZlMmQ0NjE1MmVmODVhZDY2NzliOGNiOGYxZA==
+  - - releasenotes/notes/add-volume-revert-command-1c8f695420acbe7e.yaml
+    - !!binary |
+      ZTdlYmY3NTQ0YjdiZDBiMDE0ZTlkZmZhMjdkNmM0YzYzZjA3OGY2ZQ==
+  - - releasenotes/notes/add-volume-summary-command-b2175b48af3ccab1.yaml
+    - !!binary |
+      NzcyNjZiZDljM2FmZDk0YTcwNDNkMGZhODUwNzU2NzFlN2ExNmI5Mw==
+  - - releasenotes/notes/add-workers-cleanup-command-720573c0f642efe9.yaml
+    - !!binary |
+      MmJlMzU5Njc3OTA4YjgxZDk5ODU5MTdmZDc4ZjljNjg5Nzc1OWZiOQ==
+  - - releasenotes/notes/add_volume_backend_commands_to_volumeV3-145b114e40ab8615.yaml
+    - !!binary |
+      ZjBmNTRmMDEwMDFkYjY1N2IzZWQ3ZDYxOGRmZDEwNzhmMmRkZTU4MA==
+  - - releasenotes/notes/auto-no-network-options-f4ddb2bb7544d2f5.yaml
+    - !!binary |
+      YTc5NzVjNDIwMDNkN2RmMmFmOTExNTQwMDc0MzVjZDVmODU2MGYyNA==
+  - - releasenotes/notes/bp-unshelve-to-host-9ce4b7abf81aeedf.yaml
+    - !!binary |
+      NmUwNjk5YzFjZjNlNjAzODUwNTgwYTZiYjVjYTJlMzc3ZmUxYmM4NA==
+  - - releasenotes/notes/bug-2010376-e15362bdd6c8d6ec.yaml
+    - !!binary |
+      OTEyNzdlN2U1MTg0OWQxOTc1NTRiNjMzYTU3OWM5MjExNmE1YWZjNA==
+  - - releasenotes/notes/deprecated-quota-class-options-ba33a45caedbdf3e.yaml
+    - !!binary |
+      YjYyMDIxMjYwYzljMmQzNzJlYTYzNWEyYTdmMDYwOGI3Yzg0NzJlMQ==
+  - - releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml
+    - !!binary |
+      NDQ0NDNmNzg1NjFjZTRmMjNkMjAyYTQyZGU0YTRjZWFjMmZmYTA5Nw==
+  - - releasenotes/notes/idp-auth-ttl-6632df5db65a3bdd.yaml
+    - !!binary |
+      MTY3Y2YxMWU4MjVhZjk1ZmU0MGMxZGFlZmRiNjA5NWM3OTFhM2VlNQ==
+  - - releasenotes/notes/image-import-d5da3e5ce8733fb0.yaml
+    - !!binary |
+      NGVlYTM0MDhkYzQ5MmU5NDg2NzFiNjI1ZmZjNDM3OTIxMmI1ODU3Yw==
+  - - releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml
+    - !!binary |
+      MzhmOTcyZmE2Mzc4NzFkZThhYjJhZDRhNzA3ODBmYWVmNjgzMzE5OA==
+  - - releasenotes/notes/image-stage-ac19c47e6a52ffeb.yaml
+    - !!binary |
+      MWZiOGQxZjQ4YjI1NmEyYmFkNzhlN2Q1NjMzZWE1M2M2NTM3OTA3Yw==
+  - - releasenotes/notes/network-ndp-proxy-cli-19afc530fc7061e2.yaml
+    - !!binary |
+      YjM2Y2QwZjRjMDQxNjE4MmNlNjlkNzFhNGU5OWQ4OTUwN2Q1M2U3Zg==
+  - - releasenotes/notes/network-qos-rule-type-filters-47f4911a02011501.yaml
+    - !!binary |
+      YmZhYjAxOTliZWJmMTM5YmU1YTk0OGZkZjhjZWQ4NjhiM2U5NDJkZQ==
+  - - releasenotes/notes/no-force-limit-quota-cc7f291dd1b537c1.yaml
+    - !!binary |
+      MDlmZjlhMGY0YzExOGY1MDkyNGQyZmMwNzhkNmE0NTAxZTY5NjIyNA==
+  - - releasenotes/notes/nova-gaps-server-list-to-sdk-88c8bfc10a9e3032.yaml
+    - !!binary |
+      Yzk3ZjczY2UyYTg5N2ZlNmI4M2YwOGRlMWNlNmUxODY1ZTlhODNjNQ==
+  - - releasenotes/notes/optional-volume-name-ffbefe463a598b6c.yaml
+    - !!binary |
+      M2ZjNTg1MzMyZjc5MzU4NDg5Mjg1ZWFiYzI5OGUwMTAwNzU5OTEyOA==
+  - - releasenotes/notes/quota-delete-947df66ae5341cbf.yaml
+    - !!binary |
+      NDViZWMwNDFiMjA2Njc4ZGUzNmYyZjQ2M2FjNjg3MmI3ODVlNTkyZQ==
+  - - releasenotes/notes/quota-show-service-options-ba48d6eca8ffc4f9.yaml
+    - !!binary |
+      MDBlNzAxOTAyMjU4NWJjMmJlOWFlYjU1ZWI0MGIxZDA0Nzc2ZWMyMg==
+  - - releasenotes/notes/quota-show-usage-option-19b1f59fb5f3498f.yaml
+    - !!binary |
+      MDRlNjhlMGQ1YTQ5YmU5M2Y3OWQ2ZDcxODIxYWI4Y2QwYjBjZTU4OQ==
+  - - releasenotes/notes/server-list-restrict-images-c0b2c4de6f93df33.yaml
+    - !!binary |
+      NzI1YjdkZTEzY2YwMGRhMzg2MTMyYTQyYjI3MzhmNGM1NzAyNjE4NA==
+  - - releasenotes/notes/story-2010343-b5eb4ed593f51d3f.yaml
+    - !!binary |
+      ZWM4ZGJhMjlmOWY2NDZlYzA1YzBkNmZhZDMyYjRiM2FhZjk5ZjZhZg==
+  - - releasenotes/notes/switch-hypervisor-to-sdk-2e90b26a14ffcef3.yaml
+    - !!binary |
+      MDA2ZTM1NTA5ZDNjZWE2NmRjMTNmZTIyMzhkYWM5MmY0N2ZlM2M1Yw==
+  - - releasenotes/notes/switch-hypervisor-to-sdk-f6495f070b034718.yaml
+    - !!binary |
+      OTkyY2ZkZmI1N2MzNTlmNzA5YTBjZWI2NzUwMmY1YmQ2NmI5MGU1YQ==
+  - - releasenotes/notes/switch-server-migration-to-sdk-4e4530f787f90fd2.yaml
+    - !!binary |
+      ODZjNTQ3MDEzNDhkNTE5MTM5YzUyNzIyMTk3ZDI2MmMzNWY3ZWE4ZQ==
+  - - releasenotes/notes/switch-server-show-to-sdk-44a614aebf2c6da6.yaml
+    - !!binary |
+      NzBkYmIwMWVhM2VkOTAwYTQxMDkyZDQ2ZWQ1YWUxMzcwZDU3NzFhZg==
+  version: 6.1.0
+- files:
+  - - releasenotes/notes/add-auto-approve-cleanup-a2d225faa42dfdcb.yaml
+    - !!binary |
+      NzUwNmViOGUwYzQ1OTQ5NGJkYjRlYzQ3ZGUyZTE4YTJhOTUzZDcyNw==
+  - - releasenotes/notes/add-flavor-id-to-router-create-76e916e129b5b80c.yaml
+    - !!binary |
+      ZjhmMTc0YzQ1OGE4YTMzZTFjNzI3OWNjMzI2NmVmMDA4NzM3OGE4Ng==
+  - - releasenotes/notes/add-image-metadef-resource-type-list-command-020adcaa2ad14e07.yaml
+    - !!binary |
+      NTJiZjE5NDc0MWMyNTk0ZjM4NTM5YWU2M2QzZWEzZmUwNTE1MmEwOQ==
+  - - releasenotes/notes/add-import-info-stores-delete-c50b5222c21e1077.yaml
+    - !!binary |
+      YjM0NzM0Nzk4NmViYzg2NzdjMWQ2NTYyOTkwMjBmZTU4YjFkYzJhMw==
+  - - releasenotes/notes/add-port-hints-attribute-be1779e640a47d0d.yaml
+    - !!binary |
+      MjJkMWEyNmQxZGZkNTNhNDMzN2Q1NDEzNTQ1NDQwMzFlYzZmZGQxNw==
+  - - releasenotes/notes/add-stores-info-9f1488dd29013767.yaml
+    - !!binary |
+      MThhNjE5OWVkMGRjOWQxNzNmZjE4MzAyYjg1NjE1MTQzMDc3YTg4Nw==
+  - - releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml
+    - !!binary |
+      NjI5ZWIzM2M0ZGNiNzNkNDRkMWE0YzYxMDVlNDBkMjhmNmNlYmRmYw==
+  - - releasenotes/notes/add-volume-type-set-public-private-opts-891fc7ab5de9bb6a.yaml
+    - !!binary |
+      ODNmNWM4MDMzZmEyYTI5ZGRlNDIyMjE1Mjc3YmVmZDBlYzYzMjkwZQ==
+  - - releasenotes/notes/fix-story-2010775-953dbdf03b2b6746.yaml
+    - !!binary |
+      YmM2MGUzYmI5MDhhN2YxMGM4Nzk5M2Q3OTExODRiZmU0Njc4NGQ2Yw==
+  - - releasenotes/notes/keypair-create-client-side-generation-73d8dd36192f70c9.yaml
+    - !!binary |
+      MjQ1NDYzNjM4NmQ0NDM0NzNkZWRmZjFmMDdmODYyMzEwOGU4NzI5OA==
+  - - releasenotes/notes/migrate-backup-commands-0becc8f18cf9737b.yaml
+    - !!binary |
+      YmZkNjE3MGIwM2FiNWMyMGNhZmRjOTY0NDNjZDczYjNlOGYzYWU4Mg==
+  - - releasenotes/notes/migrate-server-events-to-sdk-6a1f5dce582df245.yaml
+    - !!binary |
+      NzM3NTQwY2NhMGI4MjBjZWFmNTNmYzc0ZTgxZjRmZGFmYmM4ZjUxOA==
+  - - releasenotes/notes/migrate-server-reboot-to-sdk-a49822810def4c8a.yaml
+    - !!binary |
+      ODY0ZjUxZjQyN2MwMWQxM2M4NDA4NzgyZGQwM2JlNGI0NzNmN2IyZQ==
+  - - releasenotes/notes/migrate-server-restore-to-sdk-4540f26753031779.yaml
+    - !!binary |
+      MDA0YjJhYjJmYmFkMzY1NTkxNWYyMjZjYTJmNDc5YjM1ZjdiZmM0Ng==
+  - - releasenotes/notes/migrate-server-shelve-unshelve-to-sdk-8fce77586aa68a51.yaml
+    - !!binary |
+      ZjU2ZjBlMzMzZWQ1ODczZjcyYmU2ZWU1NTRlOGYxODQ5OWRiYjAwYg==
+  - - releasenotes/notes/migrate-server-start-stop-to-sdk-55edd4e1ff5e6ac7.yaml
+    - !!binary |
+      OTI0MTUxNDEzN2NkOGQ0NWZhNmYzNjgwODUzNmM1ZDBmMjE4Y2I5Nw==
+  - - releasenotes/notes/migrate-volume-revert-to-sdk-1e399853d80ba5f8.yaml
+    - !!binary |
+      YWFlZGEyNWUyOGJhMjdjN2U1ZDE4NzBlYmE0NDhlOTRlNGE4YWExYg==
+  - - releasenotes/notes/migrate-volume-summary-to-sdk-96ff58f653e0feaa.yaml
+    - !!binary |
+      NGRmYmM1MDExZWZlNmI1Y2QzMGQ1ZWFjMjBiOGNmMjkwMDMwMDRiMg==
+  - - releasenotes/notes/project-cleanup-skip-resource-option-4f80db0d8cf36fdb.yaml
+    - !!binary |
+      ZjI5ZTNjY2MzN2E1MTBjNDBlYTYxMjE2YWMzYTdlM2VmOTQ0ZTFiZg==
+  - - releasenotes/notes/remove-project-purge-d372374b1a7c4641.yaml
+    - !!binary |
+      NjAxZDk3MTdjMmE1YzEyNTkxMmNhMjdlNDMyNTljNDhlNTQ4OTM5Yg==
+  - - releasenotes/notes/story-2010751-server-rebuild-wait-shutoff-c84cddcd3f15e9ce.yaml
+    - !!binary |
+      NDE3YTdhZDIwMzljMDlhZGJkNDk3MzkyYzAxOTliNzY2N2U2NWVmNw==
+  - - releasenotes/notes/switch-server-lock-to-sdk-d5dd17e4987233a5.yaml
+    - !!binary |
+      Y2U4MTcxYmFkOTBmMTVhYzhhNzUzZjUwYmIzNzkyODYyYjY2Y2M3Yw==
+  version: 6.3.0
+- files:
+  - - releasenotes/notes/add-image-metadef-object-update-f4880e423bf4faba.yaml
+    - !!binary |
+      M2NkNWFkMmMxYmFiYzliZGRjODVjMWZhZjUwMDU3MjhhOTA5NzI1Yw==
+  version: 6.6.0
+- files:
+  - - releasenotes/notes/add-image-member-get-25e913ef2b861bf3.yaml
+    - !!binary |
+      OTNiMmU2NmQyZGQyNDVkMzY3NzRhMjcyNWQ2Nzg2ZWYzMjVhZTM1Yg==
+  - - releasenotes/notes/add-port-hardware-offload-type-011c98ab748357d7.yaml
+    - !!binary |
+      MDcyNWJiNDc0YzEzOGM4NGNiZTExMzFjYmY1YWI1ZDg3N2Y5ZDk2NA==
+  - - releasenotes/notes/server-create-server-group-a5b630f2a64de28d.yaml
+    - !!binary |
+      NzcwODEwNmNmMDZjZDU5MGNhNTgxODAyZDU1MDk0NDE4YmRjMWZlYg==
+  version: 6.5.0
+- files:
+  - - releasenotes/notes/Add-default-security-group-rule-CRUD-2916568f829ea38c.yaml
+    - !!binary |
+      N2I5OWI1NzE2NTQ0YmNjZjQ1NWFkMGJmNmQ4YTBjY2ZlMjc4ODMzMQ==
+  - - releasenotes/notes/add-cache-commands-a6f046348a3a0b1f.yaml
+    - !!binary |
+      YzYyOGMyZGNkM2VmYjZjZGU3ZDYzMjJjZTdmYTQwNTUwOGUyZTQ4Nw==
+  - - releasenotes/notes/add-metadef-object-create-3939ee1453585484.yaml
+    - !!binary |
+      ZjhjNzA4OTAwYzdjNTIyZDEyYjJjYTk1ZTBjMzM1MjE5ZGI3NWJmOA==
+  - - releasenotes/notes/add-metadef-object-list-c8831e73c696b9d9.yaml
+    - !!binary |
+      NGJiNmVmYThmOGVjNjBmMjg4YjFlN2EyNDZlOTdkYWNiMGY2YWQzMw==
+  - - releasenotes/notes/add-metadef-object-show-1b05dd33ecf42210.yaml
+    - !!binary |
+      NzhlZjAwOWEzYWViZTQzNTgzZDZiOTNlNjVmNTNjNDlhMWQ4MThhNg==
+  - - releasenotes/notes/add-metadef-property-create-c9a4ec2bced892af.yaml
+    - !!binary |
+      ZDljNGM0M2E0MDk5NzdlZDU5MzE2OTAxMWIxMDNiNjE4MzAyY2MwOA==
+  - - releasenotes/notes/add-metadef-property-delete-ebb999d92a588ad4.yaml
+    - !!binary |
+      OTA5NGU1NDBiNTgyMDczZjYyNjM1YzY0ZDc2MmIzYTE5ZGI3YThlNQ==
+  - - releasenotes/notes/add-metadef-property-list-fe89ae8ff9780002.yaml
+    - !!binary |
+      NWZiOTIyZTQ2OTUzOTYzZmZiZGFkZWVmM2U0ODU0ZTdhZTNjMzdiNQ==
+  - - releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml
+    - !!binary |
+      NzA1ZWNlZjdhOTQ5ZWY2ZGYwNDAxZmU5OGI2NmQxYzhkOTZkZTFkNg==
+  - - releasenotes/notes/add-metadef-property-show-8bf2ec421f74cb2d.yaml
+    - !!binary |
+      MTkwZjA2YTk2MzNmMjgwNGEwYWVmZjVkM2VmZmFjOGI3MjU1ZDI2Yw==
+  - - releasenotes/notes/block-storage-x-manageable-list-long-option-a16a4641acfcf781.yaml
+    - !!binary |
+      ODczNWI4NjJjNTJkYWFhZmZmZDNjNmQ5MWMxNGJlMjE4OTFhYzc0Yg==
+  - - releasenotes/notes/migrate-resource-filter-commands-2a353edb965723d1.yaml
+    - !!binary |
+      YWUxMDg1MWE2ODJhZGIxZGI3ZDNkY2EyNzk0NDE1NDM3YzJlYWE3OQ==
+  - - releasenotes/notes/migrate-volume-backend-commands-259e553e213c71b0.yaml
+    - !!binary |
+      MzlhMDg0ZjkxY2Q1ODBiZTZhZGY0NmU4ZTc1MjIzMzExMmY2ZWM3NA==
+  - - releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml
+    - !!binary |
+      YTM0MTBjZDRmNzg1ZWMxODg5NzNkODU1MDk0NDhhMzIwZTg4MjUxNA==
+  - - releasenotes/notes/volume-type-list-properties-filter-8532f96d16733915.yaml
+    - !!binary |
+      NjdiZWM3Nzg1Y2UyZTFhZjc0NWE1NWQxODM4MzE1ZGM2ZTg0OWVhYQ==
+  version: 6.4.0
+- files:
+  - - releasenotes/notes/bug-2084580-cb1e8c47501e730c.yaml
+    - !!binary |
+      YzY5NDZmNDc0MzUzMzQ0OWI1YjhhM2RiMmIxYThmZTA5OWI4NDJkYQ==
+  version: 7.1.4
+- files:
+  - - releasenotes/notes/aggregate-list-uuid-column-808a0d051006a5ef.yaml
+    - !!binary |
+      MDRlYmUwODUzZDFmNTliOGExOGZjYjhjOGFmZmZiYzIzZGQwZWZjNA==
+  version: 7.1.0
+- files:
+  - - releasenotes/notes/Router-flavor-accepts-name-or-id-e9cecafcddf81cb2.yaml
+    - !!binary |
+      MmU3YmE1ZTNkZDgwNTVlN2ViMmRjYWM5ZGIxMDA5ZGI1MTJhN2ZjYw==
+  - - releasenotes/notes/add-cluster-to-service-list-5eab3e828de7547e.yaml
+    - !!binary |
+      Y2E4MWIxYWNmMDVkODc4NzFhZTJjNjcyZDc5MDBkZmI2N2Q1MmVjMA==
+  - - releasenotes/notes/add-image-metadef-object-property-show-4ab2c957451ea230.yaml
+    - !!binary |
+      MmE5MGE2ZjA3YjUyNzYwYjk0NDI0OTNkNGMzODJkN2U2ZWUxY2VkMg==
+  - - releasenotes/notes/add-image-metadef-resource-type-association-commands-4d373d7d8eca5d55.yaml
+    - !!binary |
+      Mjc2ZGJiNmY1NjMwY2Y5NmYyNjBjOGUzNDdlODUyOTNiODZhODc2Zg==
+  - - releasenotes/notes/add-port-numa-affinity-policy-socket-5a986b14033e0f6e.yaml
+    - !!binary |
+      OTY2MDUxY2ZlMmUzNWMyYTljOGE0OTdiZjVhNmI2MjZiYTE5MmIwYw==
+  - - releasenotes/notes/add-snapshot-unmanage-command-d4c0c8fd8b638d48.yaml
+    - !!binary |
+      NGU5NGM0MTVlZDU3YzBkNjM2NmE3ZTQ5MjU5ZTc5ZmQ2NTA1ZWQ2YQ==
+  - - releasenotes/notes/add-volume-manage-command-088890446d0e81c7.yaml
+    - !!binary |
+      Y2M3NzczZjUzYmFjNjFmNjAyY2U4ZWJjOTA4ODc4ZmQwOTE0NzI0Yw==
+  - - releasenotes/notes/add-volume-unmanage-support-9b7139e5e948de77.yaml
+    - !!binary |
+      ZmRjMjc2M2FjMjA1MmYxMjFlOTE5YTg1MTMxMTllOTVkZGQzNjJkOA==
+  - - releasenotes/notes/fix-backup-incremental-d1c1e6886cf32256.yaml
+    - !!binary |
+      MjA1YmFjM2NhZjVmZjk4M2M2MGRhMGQxNzFlNTFjMWNjMjg2MDI0YQ==
+  - - releasenotes/notes/migrate-agent-commands-1c50ffcb75f91418.yaml
+    - !!binary |
+      MGYwN2M5N2U4NDdiOGRhNzUyMDhiZjdlZWRmNjYxN2QyMmVkNjVhNQ==
+  - - releasenotes/notes/migrate-application-credential-to-sdk-c79d8dfc3c8e1d9f.yaml
+    - !!binary |
+      YmVmOGE3YTYzMDk4ZjkwM2JjZDJhOWQ0MmYyZjM3NDU4NjAyMzQwZg==
+  - - releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml
+    - !!binary |
+      NzI1MmE3YTc4MTdmNTdjMmYzOGQwZjViZjEwNzM5ZmYxZmE1ODMyMA==
+  - - releasenotes/notes/migrate-limits-show-f586c9762dfd7d0c.yaml
+    - !!binary |
+      OWQzOTQzNzI4MjMwNTNlNmE0MDM4ZTE0ZjgxZTE0ZDFhMzJhNmUzYg==
+  - - releasenotes/notes/migrate-role-assignment-to-sdk-e6e52bef467b4e4c.yaml
+    - !!binary |
+      ZGU5ZDBmOWUxYjUxMWM2YWNhN2RlYTU3ZjYyMzMxYmIyNjM4ZWYxOA==
+  - - releasenotes/notes/migrate-server-evacuate-to-sdk-a0415988ef5451b2.yaml
+    - !!binary |
+      ZTZkYzBmMzljMDg5MWVhNTUxODY3Yjc3NjYzYTQ2M2I1Zjc2OTg3Yw==
+  - - releasenotes/notes/migrate-server-set-unset-to-sdk-ae32ebcced845b06.yaml
+    - !!binary |
+      YmNhZjJhYjU1OWU4MmQ1NzFjZjQ2ZWQ1MGFiYTYwYWJmMGI0MTYzNw==
+  - - releasenotes/notes/migrate-service-to-sdk-6ff62ebf7e41db7c.yaml
+    - !!binary |
+      NzE3ZjI0Mjg4MWZmNThmMWRkZWM5OTRmZmM2OGI4MjEwM2NhN2RhYg==
+  - - releasenotes/notes/migrate-volume-attachment-commands-4309409bca1ca5d4.yaml
+    - !!binary |
+      OWYzMGVlOWFmMmY0M2QwNzU0OTU2NDU0YWIwOGNiMGExMGU4NDdmNA==
+  - - releasenotes/notes/network-quota-no-force-default-0975bdf15655070c.yaml
+    - !!binary |
+      ZGE3ZWRhNjZlOTZhNzJlN2Y1MWE5YzZiZWJiNDcyMjUwM2NjOTY2Mg==
+  - - releasenotes/notes/quota-set-default-option-bc26d37dc150533b.yaml
+    - !!binary |
+      N2Q4YmFhODdiYmExMDAzZDYxZjA4ZjBkMjBhNDc0ODUxM2UxYzQ1YQ==
+  - - releasenotes/notes/remove-deprecated-quota-show-class-option-2109a6ff7ac18e80.yaml
+    - !!binary |
+      YmEyZDIzNThlNjE0YjhkZWYxMzgzNGM3NjBiYTU1MWU5NzNiMzNiMQ==
+  - - releasenotes/notes/rename-volume-set-retype-policy-6bacb7dd92f1ad82.yaml
+    - !!binary |
+      NWExOGY5OTVhOGVmMzFlZmI5YWIzMjRlMmI1YzllNTcyZTc1YzJkMQ==
+  version: 7.0.0
+- files:
+  - - releasenotes/notes/port_uplink_status_propagation_updatable-d1e155c19247b666.yaml
+    - !!binary |
+      NDI2YWJiZGM2ODFkM2YzNmYxODZmZDY4NWEzZjFjMGI2MDU4ZjYyNg==
+  version: 7.4.0
+- files:
+  - - releasenotes/notes/Add-trusted-vif-to-the-port-0a0c76d9da8f3da0.yaml
+    - !!binary |
+      NDcxNDQxMDNjYWJmMTFlZGIxMDhhZTgwZjcwMGVhOTM2YmY1MGIzMA==
+  - - releasenotes/notes/add-vlan_qinq-to-the-network-3556c094aeedc0de.yaml
+    - !!binary |
+      MzQxMjE0NzM3MjJiMWUxMGJhOWI2NGFmOWEzNTE3ZGMyZDZlNDIyZg==
+  - - releasenotes/notes/fix-restore-resp-e664a643a723cd2e.yaml
+    - !!binary |
+      MDNlMmZkZDE2MjJkNzliMDE5OWUzNDliZTA0Mjk5MWY5MjdmMDQxNA==
+  - - releasenotes/notes/fix-show-backup-by-name-0759c55396be77a3.yaml
+    - !!binary |
+      YjZiMTg0ODliMGIxYjIwMGM0MGUwNjBmNmM4MzAxMDMwNzBkOTBmNQ==
+  - - releasenotes/notes/migrate-credential-to-sdk-33a841847fe7d568.yaml
+    - !!binary |
+      OWM2ZGY4MjNlMjRmY2I5NDgyM2ViY2U5NTE1OTczMzg2Y2ZlZDM3Mg==
+  - - releasenotes/notes/migrate-region-to-sdk-fbd27bceaa1db9dc.yaml
+    - !!binary |
+      NGM4MjkwMDEyZDYwYjFiNTM1NTk0Zjk1ZGJjNWE5ZTE4ZGI3MjFlYQ==
+  - - releasenotes/notes/migrate-service-provider-to-sdk-74dc48b227f21a05.yaml
+    - !!binary |
+      NTZiYWY1MDY1NWNmZTc5NDhjYTVlMDEwYjkzNzc3NDkwNjZiNmJmOQ==
+  - - releasenotes/notes/migrate-trust-to-sdk-9397c9cfddcb636a.yaml
+    - !!binary |
+      NzY5YmY4N2QwYTJhMzA1ZDljZTUzYzkxOTMxZjFjNzAxNjg0ODA1Mw==
+  - - releasenotes/notes/server-create-no-security-group-option-627697bddae429b1.yaml
+    - !!binary |
+      NWVmNWNjOWM4Mjc5OTI5MDk2MmI4MGFhNjYzYWYwMDk0NTcyYzkwMw==
+  - - releasenotes/notes/volume-backup-created-at-list-v3-47400b31be5143bc.yaml
+    - !!binary |
+      Njk1ZDAyNWYwMDI4ZGFlMjcxNTA5NmI1MzYyOWYxYTAwODEwZDI3MA==
+  version: 7.3.0
+- files:
+  - - releasenotes/notes/bug-2084580-cb1e8c47501e730c.yaml
+    - !!binary |
+      N2M2YjQ3YjQ1MWYzMGQxZDM5NjUzNThjNTE1YmFhZTg3OTU1ZDdkYw==
+  version: 7.2.1
+- files:
+  - - releasenotes/notes/add-port-list-status-option-f51da0aed0528a5d.yaml
+    - !!binary |
+      OWMyMjM2OTZhMGUzYjQ1YmNkOGJjYjBhOGY4MWUzMzU0Y2NlYTljNg==
+  - - releasenotes/notes/add-remove-multiple-security-groups-2c0b2d599124c9c9.yaml
+    - !!binary |
+      ZWNlMzBlOGY3MDNmOTE4ZTM5MWU5MzRlY2QyYjIwMWYyMTFiZmJmZQ==
+  - - releasenotes/notes/drop-python-38-9dcbd2b2b51f24f2.yaml
+    - !!binary |
+      N2E5MmJjNGFiYzQ1ODdjMjcwZmQ4NmZkYzQ0ZjIzMWZkYWI3YWI5Ng==
+  - - releasenotes/notes/migrate-access-rule-to-sdk-923682b4c71fea8a.yaml
+    - !!binary |
+      NDE1ZjY4MDE2Y2E3ODNiNWU0NGFhNmIxNTJjNzEzNjQ2MzQ2N2FiMA==
+  version: 7.2.0
diff -pruN 7.4.0-3/releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml
--- 7.4.0-3/releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/notes/router-create-with-qos-policy-b94967a35351cddd.yaml	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    The router creation command now has the parameter ``--qos-policy``, that
+    allows to set a QoS policy for the provided external gateways (one or
+    many). It is mandatory to define an external gateway if the QoS policy is
+    set.
diff -pruN 7.4.0-3/releasenotes/source/2025.1.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/source/2025.1.rst
--- 7.4.0-3/releasenotes/source/2025.1.rst	1970-01-01 00:00:00.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/source/2025.1.rst	2025-07-07 22:41:56.000000000 +0000
@@ -0,0 +1,6 @@
+===========================
+2025.1 Series Release Notes
+===========================
+
+.. release-notes::
+   :branch: stable/2025.1
diff -pruN 7.4.0-3/releasenotes/source/index.rst 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/source/index.rst
--- 7.4.0-3/releasenotes/source/index.rst	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/releasenotes/source/index.rst	2025-07-07 22:41:56.000000000 +0000
@@ -6,6 +6,7 @@ OpenStackClient Release Notes
    :maxdepth: 1
 
    unreleased
+   2025.1
    2024.2
    2024.1
    2023.2
diff -pruN 7.4.0-3/requirements.txt 8.1.0+git2025070715.9d3a956a-0ubuntu2/requirements.txt
--- 7.4.0-3/requirements.txt	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/requirements.txt	2025-07-07 22:41:56.000000000 +0000
@@ -5,9 +5,9 @@
 pbr!=2.1.0,>=2.0.0 # Apache-2.0
 
 cryptography>=2.7 # BSD/Apache-2.0
-cliff>=3.5.0 # Apache-2.0
+cliff>=4.8.0 # Apache-2.0
 iso8601>=0.1.11 # MIT
-openstacksdk>=3.3.0 # Apache-2.0
+openstacksdk>=4.5.0 # Apache-2.0
 osc-lib>=2.3.0 # Apache-2.0
 oslo.i18n>=3.15.3 # Apache-2.0
 python-keystoneclient>=3.22.0 # Apache-2.0
diff -pruN 7.4.0-3/setup.cfg 8.1.0+git2025070715.9d3a956a-0ubuntu2/setup.cfg
--- 7.4.0-3/setup.cfg	2025-02-25 22:48:45.000000000 +0000
+++ 8.1.0+git2025070715.9d3a956a-0ubuntu2/setup.cfg	2025-07-07 22:42:17.978110300 +0000
@@ -1,865 +1,7 @@
 [metadata]
 name = python-openstackclient
-summary = OpenStack Command-line Client
-description_file =
-    README.rst
-author = OpenStack
-author_email = openstack-discuss@lists.openstack.org
-home_page = https://docs.openstack.org/python-openstackclient/latest/
-python_requires = >=3.9
-classifier =
-    Environment :: OpenStack
-    Intended Audience :: Information Technology
-    Intended Audience :: System Administrators
-    License :: OSI Approved :: Apache Software License
-    Operating System :: POSIX :: Linux
-    Programming Language :: Python
-    Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.9
-    Programming Language :: Python :: 3.10
-    Programming Language :: Python :: 3.11
-    Programming Language :: Python :: 3.12
 
-[files]
-packages =
-    openstackclient
+[egg_info]
+tag_build = 
+tag_date = 0
 
-[entry_points]
-console_scripts =
-    openstack = openstackclient.shell:main
-
-openstack.cli =
-    command_list = openstackclient.common.module:ListCommand
-    module_list = openstackclient.common.module:ListModule
-
-openstack.cli.base =
-    compute = openstackclient.compute.client
-    identity = openstackclient.identity.client
-    image = openstackclient.image.client
-    network = openstackclient.network.client
-    object_store = openstackclient.object.client
-    volume = openstackclient.volume.client
-
-openstack.common =
-    availability_zone_list = openstackclient.common.availability_zone:ListAvailabilityZone
-    configuration_show = openstackclient.common.configuration:ShowConfiguration
-    extension_list = openstackclient.common.extension:ListExtension
-    extension_show = openstackclient.common.extension:ShowExtension
-    limits_show = openstackclient.common.limits:ShowLimits
-    project_cleanup = openstackclient.common.project_cleanup:ProjectCleanup
-    quota_list = openstackclient.common.quota:ListQuota
-    quota_set = openstackclient.common.quota:SetQuota
-    quota_show = openstackclient.common.quota:ShowQuota
-    quota_delete = openstackclient.common.quota:DeleteQuota
-    versions_show = openstackclient.common.versions:ShowVersions
-
-openstack.compute.v2 =
-    compute_agent_create = openstackclient.compute.v2.agent:CreateAgent
-    compute_agent_delete = openstackclient.compute.v2.agent:DeleteAgent
-    compute_agent_list = openstackclient.compute.v2.agent:ListAgent
-    compute_agent_set = openstackclient.compute.v2.agent:SetAgent
-
-    aggregate_add_host = openstackclient.compute.v2.aggregate:AddAggregateHost
-    aggregate_create = openstackclient.compute.v2.aggregate:CreateAggregate
-    aggregate_delete = openstackclient.compute.v2.aggregate:DeleteAggregate
-    aggregate_list = openstackclient.compute.v2.aggregate:ListAggregate
-    aggregate_remove_host = openstackclient.compute.v2.aggregate:RemoveAggregateHost
-    aggregate_set = openstackclient.compute.v2.aggregate:SetAggregate
-    aggregate_show = openstackclient.compute.v2.aggregate:ShowAggregate
-    aggregate_unset = openstackclient.compute.v2.aggregate:UnsetAggregate
-    aggregate_cache_image = openstackclient.compute.v2.aggregate:CacheImageForAggregate
-
-    compute_service_delete = openstackclient.compute.v2.service:DeleteService
-    compute_service_list = openstackclient.compute.v2.service:ListService
-    compute_service_set = openstackclient.compute.v2.service:SetService
-
-    console_log_show = openstackclient.compute.v2.console:ShowConsoleLog
-    console_url_show = openstackclient.compute.v2.console:ShowConsoleURL
-
-    flavor_create = openstackclient.compute.v2.flavor:CreateFlavor
-    flavor_delete = openstackclient.compute.v2.flavor:DeleteFlavor
-    flavor_list = openstackclient.compute.v2.flavor:ListFlavor
-    flavor_show = openstackclient.compute.v2.flavor:ShowFlavor
-    flavor_set = openstackclient.compute.v2.flavor:SetFlavor
-    flavor_unset = openstackclient.compute.v2.flavor:UnsetFlavor
-
-    host_list = openstackclient.compute.v2.host:ListHost
-    host_set = openstackclient.compute.v2.host:SetHost
-    host_show = openstackclient.compute.v2.host:ShowHost
-
-    hypervisor_list = openstackclient.compute.v2.hypervisor:ListHypervisor
-    hypervisor_show = openstackclient.compute.v2.hypervisor:ShowHypervisor
-
-    hypervisor_stats_show = openstackclient.compute.v2.hypervisor_stats:ShowHypervisorStats
-
-    keypair_create = openstackclient.compute.v2.keypair:CreateKeypair
-    keypair_delete = openstackclient.compute.v2.keypair:DeleteKeypair
-    keypair_list = openstackclient.compute.v2.keypair:ListKeypair
-    keypair_show = openstackclient.compute.v2.keypair:ShowKeypair
-
-    server_add_fixed_ip = openstackclient.compute.v2.server:AddFixedIP
-    server_add_floating_ip = openstackclient.compute.v2.server:AddFloatingIP
-    server_add_port = openstackclient.compute.v2.server:AddPort
-    server_add_network = openstackclient.compute.v2.server:AddNetwork
-    server_add_security_group = openstackclient.compute.v2.server:AddServerSecurityGroup
-    server_add_volume = openstackclient.compute.v2.server:AddServerVolume
-    server_create = openstackclient.compute.v2.server:CreateServer
-    server_delete = openstackclient.compute.v2.server:DeleteServer
-    server_dump_create = openstackclient.compute.v2.server:CreateServerDump
-    server_evacuate = openstackclient.compute.v2.server:EvacuateServer
-    server_list = openstackclient.compute.v2.server:ListServer
-    server_lock = openstackclient.compute.v2.server:LockServer
-    server_migrate = openstackclient.compute.v2.server:MigrateServer
-    server_migrate_confirm = openstackclient.compute.v2.server:MigrateConfirm
-    server_migrate_revert = openstackclient.compute.v2.server:MigrateRevert
-    server_migration_confirm = openstackclient.compute.v2.server:ConfirmMigration
-    server_migration_revert = openstackclient.compute.v2.server:RevertMigration
-    server_pause = openstackclient.compute.v2.server:PauseServer
-    server_reboot = openstackclient.compute.v2.server:RebootServer
-    server_rebuild = openstackclient.compute.v2.server:RebuildServer
-    server_remove_fixed_ip = openstackclient.compute.v2.server:RemoveFixedIP
-    server_remove_floating_ip = openstackclient.compute.v2.server:RemoveFloatingIP
-    server_remove_port = openstackclient.compute.v2.server:RemovePort
-    server_remove_network = openstackclient.compute.v2.server:RemoveNetwork
-    server_remove_security_group = openstackclient.compute.v2.server:RemoveServerSecurityGroup
-    server_remove_volume = openstackclient.compute.v2.server:RemoveServerVolume
-    server_rescue = openstackclient.compute.v2.server:RescueServer
-    server_resize = openstackclient.compute.v2.server:ResizeServer
-    server_resize_confirm = openstackclient.compute.v2.server:ResizeConfirm
-    server_resize_revert = openstackclient.compute.v2.server:ResizeRevert
-    server_restore = openstackclient.compute.v2.server:RestoreServer
-    server_resume = openstackclient.compute.v2.server:ResumeServer
-    server_set = openstackclient.compute.v2.server:SetServer
-    server_shelve = openstackclient.compute.v2.server:ShelveServer
-    server_show = openstackclient.compute.v2.server:ShowServer
-    server_ssh = openstackclient.compute.v2.server:SshServer
-    server_start = openstackclient.compute.v2.server:StartServer
-    server_stop = openstackclient.compute.v2.server:StopServer
-    server_suspend = openstackclient.compute.v2.server:SuspendServer
-    server_unlock = openstackclient.compute.v2.server:UnlockServer
-    server_unpause = openstackclient.compute.v2.server:UnpauseServer
-    server_unrescue = openstackclient.compute.v2.server:UnrescueServer
-    server_unset = openstackclient.compute.v2.server:UnsetServer
-    server_unshelve = openstackclient.compute.v2.server:UnshelveServer
-
-    server_backup_create = openstackclient.compute.v2.server_backup:CreateServerBackup
-
-    server_event_list = openstackclient.compute.v2.server_event:ListServerEvent
-    server_event_show = openstackclient.compute.v2.server_event:ShowServerEvent
-
-    server_group_create = openstackclient.compute.v2.server_group:CreateServerGroup
-    server_group_delete = openstackclient.compute.v2.server_group:DeleteServerGroup
-    server_group_list = openstackclient.compute.v2.server_group:ListServerGroup
-    server_group_show = openstackclient.compute.v2.server_group:ShowServerGroup
-
-    server_image_create = openstackclient.compute.v2.server_image:CreateServerImage
-
-    server_migration_abort = openstackclient.compute.v2.server_migration:AbortMigration
-    server_migration_force_complete = openstackclient.compute.v2.server_migration:ForceCompleteMigration
-    server_migration_list = openstackclient.compute.v2.server_migration:ListMigration
-    server_migration_show = openstackclient.compute.v2.server_migration:ShowMigration
-
-    server_volume_list = openstackclient.compute.v2.server_volume:ListServerVolume
-    server_volume_set = openstackclient.compute.v2.server_volume:SetServerVolume
-    server_volume_update = openstackclient.compute.v2.server_volume:UpdateServerVolume
-
-    usage_list = openstackclient.compute.v2.usage:ListUsage
-    usage_show = openstackclient.compute.v2.usage:ShowUsage
-
-openstack.identity.v2 =
-    catalog_list = openstackclient.identity.v2_0.catalog:ListCatalog
-    catalog_show = openstackclient.identity.v2_0.catalog:ShowCatalog
-
-    ec2_credentials_create = openstackclient.identity.v2_0.ec2creds:CreateEC2Creds
-    ec2_credentials_delete = openstackclient.identity.v2_0.ec2creds:DeleteEC2Creds
-    ec2_credentials_list = openstackclient.identity.v2_0.ec2creds:ListEC2Creds
-    ec2_credentials_show = openstackclient.identity.v2_0.ec2creds:ShowEC2Creds
-
-    endpoint_create = openstackclient.identity.v2_0.endpoint:CreateEndpoint
-    endpoint_delete = openstackclient.identity.v2_0.endpoint:DeleteEndpoint
-    endpoint_list = openstackclient.identity.v2_0.endpoint:ListEndpoint
-    endpoint_show = openstackclient.identity.v2_0.endpoint:ShowEndpoint
-
-    project_create = openstackclient.identity.v2_0.project:CreateProject
-    project_delete = openstackclient.identity.v2_0.project:DeleteProject
-    project_list = openstackclient.identity.v2_0.project:ListProject
-    project_set = openstackclient.identity.v2_0.project:SetProject
-    project_show = openstackclient.identity.v2_0.project:ShowProject
-    project_unset = openstackclient.identity.v2_0.project:UnsetProject
-
-    role_add = openstackclient.identity.v2_0.role:AddRole
-    role_create = openstackclient.identity.v2_0.role:CreateRole
-    role_delete = openstackclient.identity.v2_0.role:DeleteRole
-    role_list = openstackclient.identity.v2_0.role:ListRole
-    role_remove = openstackclient.identity.v2_0.role:RemoveRole
-    role_show = openstackclient.identity.v2_0.role:ShowRole
-    role_assignment_list = openstackclient.identity.v2_0.role_assignment:ListRoleAssignment
-
-    service_create = openstackclient.identity.v2_0.service:CreateService
-    service_delete = openstackclient.identity.v2_0.service:DeleteService
-    service_list = openstackclient.identity.v2_0.service:ListService
-    service_show = openstackclient.identity.v2_0.service:ShowService
-
-    token_issue = openstackclient.identity.v2_0.token:IssueToken
-    token_revoke = openstackclient.identity.v2_0.token:RevokeToken
-
-    user_create = openstackclient.identity.v2_0.user:CreateUser
-    user_delete = openstackclient.identity.v2_0.user:DeleteUser
-    user_list = openstackclient.identity.v2_0.user:ListUser
-    user_set = openstackclient.identity.v2_0.user:SetUser
-    user_show = openstackclient.identity.v2_0.user:ShowUser
-
-openstack.identity.v3 =
-    access_token_create = openstackclient.identity.v3.token:CreateAccessToken
-
-    access_rule_delete = openstackclient.identity.v3.access_rule:DeleteAccessRule
-    access_rule_list = openstackclient.identity.v3.access_rule:ListAccessRule
-    access_rule_show = openstackclient.identity.v3.access_rule:ShowAccessRule
-
-    application_credential_create = openstackclient.identity.v3.application_credential:CreateApplicationCredential
-    application_credential_delete = openstackclient.identity.v3.application_credential:DeleteApplicationCredential
-    application_credential_list = openstackclient.identity.v3.application_credential:ListApplicationCredential
-    application_credential_show = openstackclient.identity.v3.application_credential:ShowApplicationCredential
-
-    catalog_list = openstackclient.identity.v3.catalog:ListCatalog
-    catalog_show = openstackclient.identity.v3.catalog:ShowCatalog
-
-    consumer_create = openstackclient.identity.v3.consumer:CreateConsumer
-    consumer_delete = openstackclient.identity.v3.consumer:DeleteConsumer
-    consumer_list = openstackclient.identity.v3.consumer:ListConsumer
-    consumer_set = openstackclient.identity.v3.consumer:SetConsumer
-    consumer_show = openstackclient.identity.v3.consumer:ShowConsumer
-
-    credential_create = openstackclient.identity.v3.credential:CreateCredential
-    credential_delete = openstackclient.identity.v3.credential:DeleteCredential
-    credential_list = openstackclient.identity.v3.credential:ListCredential
-    credential_set = openstackclient.identity.v3.credential:SetCredential
-    credential_show = openstackclient.identity.v3.credential:ShowCredential
-
-    domain_create = openstackclient.identity.v3.domain:CreateDomain
-    domain_delete = openstackclient.identity.v3.domain:DeleteDomain
-    domain_list = openstackclient.identity.v3.domain:ListDomain
-    domain_set = openstackclient.identity.v3.domain:SetDomain
-    domain_show = openstackclient.identity.v3.domain:ShowDomain
-
-    ec2_credentials_create = openstackclient.identity.v3.ec2creds:CreateEC2Creds
-    ec2_credentials_delete = openstackclient.identity.v3.ec2creds:DeleteEC2Creds
-    ec2_credentials_list = openstackclient.identity.v3.ec2creds:ListEC2Creds
-    ec2_credentials_show = openstackclient.identity.v3.ec2creds:ShowEC2Creds
-
-    endpoint_add_project = openstackclient.identity.v3.endpoint:AddProjectToEndpoint
-    endpoint_create = openstackclient.identity.v3.endpoint:CreateEndpoint
-    endpoint_delete = openstackclient.identity.v3.endpoint:DeleteEndpoint
-    endpoint_list = openstackclient.identity.v3.endpoint:ListEndpoint
-    endpoint_remove_project = openstackclient.identity.v3.endpoint:RemoveProjectFromEndpoint
-    endpoint_set = openstackclient.identity.v3.endpoint:SetEndpoint
-    endpoint_show = openstackclient.identity.v3.endpoint:ShowEndpoint
-
-    endpoint_group_add_project = openstackclient.identity.v3.endpoint_group:AddProjectToEndpointGroup
-    endpoint_group_create = openstackclient.identity.v3.endpoint_group:CreateEndpointGroup
-    endpoint_group_delete = openstackclient.identity.v3.endpoint_group:DeleteEndpointGroup
-    endpoint_group_list = openstackclient.identity.v3.endpoint_group:ListEndpointGroup
-    endpoint_group_remove_project = openstackclient.identity.v3.endpoint_group:RemoveProjectFromEndpointGroup
-    endpoint_group_set = openstackclient.identity.v3.endpoint_group:SetEndpointGroup
-    endpoint_group_show = openstackclient.identity.v3.endpoint_group:ShowEndpointGroup
-
-    federation_domain_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleDomains
-    federation_project_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleProjects
-
-    federation_protocol_create = openstackclient.identity.v3.federation_protocol:CreateProtocol
-    federation_protocol_delete = openstackclient.identity.v3.federation_protocol:DeleteProtocol
-    federation_protocol_list = openstackclient.identity.v3.federation_protocol:ListProtocols
-    federation_protocol_set = openstackclient.identity.v3.federation_protocol:SetProtocol
-    federation_protocol_show = openstackclient.identity.v3.federation_protocol:ShowProtocol
-
-    group_add_user = openstackclient.identity.v3.group:AddUserToGroup
-    group_contains_user = openstackclient.identity.v3.group:CheckUserInGroup
-    group_create = openstackclient.identity.v3.group:CreateGroup
-    group_delete = openstackclient.identity.v3.group:DeleteGroup
-    group_list = openstackclient.identity.v3.group:ListGroup
-    group_remove_user = openstackclient.identity.v3.group:RemoveUserFromGroup
-    group_set = openstackclient.identity.v3.group:SetGroup
-    group_show = openstackclient.identity.v3.group:ShowGroup
-
-    identity_provider_create = openstackclient.identity.v3.identity_provider:CreateIdentityProvider
-    identity_provider_delete = openstackclient.identity.v3.identity_provider:DeleteIdentityProvider
-    identity_provider_list = openstackclient.identity.v3.identity_provider:ListIdentityProvider
-    identity_provider_set = openstackclient.identity.v3.identity_provider:SetIdentityProvider
-    identity_provider_show = openstackclient.identity.v3.identity_provider:ShowIdentityProvider
-
-    implied_role_create = openstackclient.identity.v3.implied_role:CreateImpliedRole
-    implied_role_delete = openstackclient.identity.v3.implied_role:DeleteImpliedRole
-    implied_role_list = openstackclient.identity.v3.implied_role:ListImpliedRole
-
-    limit_create = openstackclient.identity.v3.limit:CreateLimit
-    limit_delete = openstackclient.identity.v3.limit:DeleteLimit
-    limit_list = openstackclient.identity.v3.limit:ListLimit
-    limit_set = openstackclient.identity.v3.limit:SetLimit
-    limit_show = openstackclient.identity.v3.limit:ShowLimit
-
-    mapping_create = openstackclient.identity.v3.mapping:CreateMapping
-    mapping_delete = openstackclient.identity.v3.mapping:DeleteMapping
-    mapping_list = openstackclient.identity.v3.mapping:ListMapping
-    mapping_set = openstackclient.identity.v3.mapping:SetMapping
-    mapping_show = openstackclient.identity.v3.mapping:ShowMapping
-
-    policy_create = openstackclient.identity.v3.policy:CreatePolicy
-    policy_delete = openstackclient.identity.v3.policy:DeletePolicy
-    policy_list = openstackclient.identity.v3.policy:ListPolicy
-    policy_set = openstackclient.identity.v3.policy:SetPolicy
-    policy_show = openstackclient.identity.v3.policy:ShowPolicy
-
-    project_create = openstackclient.identity.v3.project:CreateProject
-    project_delete = openstackclient.identity.v3.project:DeleteProject
-    project_list = openstackclient.identity.v3.project:ListProject
-    project_set = openstackclient.identity.v3.project:SetProject
-    project_show = openstackclient.identity.v3.project:ShowProject
-
-    region_create = openstackclient.identity.v3.region:CreateRegion
-    region_delete = openstackclient.identity.v3.region:DeleteRegion
-    region_list = openstackclient.identity.v3.region:ListRegion
-    region_set = openstackclient.identity.v3.region:SetRegion
-    region_show = openstackclient.identity.v3.region:ShowRegion
-
-    registered_limit_create = openstackclient.identity.v3.registered_limit:CreateRegisteredLimit
-    registered_limit_delete = openstackclient.identity.v3.registered_limit:DeleteRegisteredLimit
-    registered_limit_list = openstackclient.identity.v3.registered_limit:ListRegisteredLimit
-    registered_limit_set = openstackclient.identity.v3.registered_limit:SetRegisteredLimit
-    registered_limit_show = openstackclient.identity.v3.registered_limit:ShowRegisteredLimit
-
-    request_token_authorize = openstackclient.identity.v3.token:AuthorizeRequestToken
-    request_token_create = openstackclient.identity.v3.token:CreateRequestToken
-
-    role_add = openstackclient.identity.v3.role:AddRole
-    role_create = openstackclient.identity.v3.role:CreateRole
-    role_delete = openstackclient.identity.v3.role:DeleteRole
-    role_list = openstackclient.identity.v3.role:ListRole
-    role_remove = openstackclient.identity.v3.role:RemoveRole
-    role_show = openstackclient.identity.v3.role:ShowRole
-    role_set = openstackclient.identity.v3.role:SetRole
-    role_assignment_list = openstackclient.identity.v3.role_assignment:ListRoleAssignment
-
-    service_create = openstackclient.identity.v3.service:CreateService
-    service_delete = openstackclient.identity.v3.service:DeleteService
-    service_list = openstackclient.identity.v3.service:ListService
-    service_show = openstackclient.identity.v3.service:ShowService
-    service_set = openstackclient.identity.v3.service:SetService
-
-    service_provider_create = openstackclient.identity.v3.service_provider:CreateServiceProvider
-    service_provider_delete = openstackclient.identity.v3.service_provider:DeleteServiceProvider
-    service_provider_list = openstackclient.identity.v3.service_provider:ListServiceProvider
-    service_provider_set = openstackclient.identity.v3.service_provider:SetServiceProvider
-    service_provider_show = openstackclient.identity.v3.service_provider:ShowServiceProvider
-
-    token_issue = openstackclient.identity.v3.token:IssueToken
-    token_revoke = openstackclient.identity.v3.token:RevokeToken
-
-    trust_create = openstackclient.identity.v3.trust:CreateTrust
-    trust_delete = openstackclient.identity.v3.trust:DeleteTrust
-    trust_list = openstackclient.identity.v3.trust:ListTrust
-    trust_show = openstackclient.identity.v3.trust:ShowTrust
-
-    user_create = openstackclient.identity.v3.user:CreateUser
-    user_delete = openstackclient.identity.v3.user:DeleteUser
-    user_list = openstackclient.identity.v3.user:ListUser
-    user_set = openstackclient.identity.v3.user:SetUser
-    user_password_set = openstackclient.identity.v3.user:SetPasswordUser
-    user_show = openstackclient.identity.v3.user:ShowUser
-
-openstack.image.v1 =
-    image_create = openstackclient.image.v1.image:CreateImage
-    image_delete = openstackclient.image.v1.image:DeleteImage
-    image_list = openstackclient.image.v1.image:ListImage
-    image_save = openstackclient.image.v1.image:SaveImage
-    image_set = openstackclient.image.v1.image:SetImage
-    image_show = openstackclient.image.v1.image:ShowImage
-
-openstack.image.v2 =
-    image_add_project = openstackclient.image.v2.image:AddProjectToImage
-    image_create = openstackclient.image.v2.image:CreateImage
-    image_delete = openstackclient.image.v2.image:DeleteImage
-    image_list = openstackclient.image.v2.image:ListImage
-    image_member_list = openstackclient.image.v2.image:ListImageProjects
-    image_remove_project = openstackclient.image.v2.image:RemoveProjectImage
-    image_member_get = openstackclient.image.v2.image:ShowProjectImage
-    image_save = openstackclient.image.v2.image:SaveImage
-    image_show = openstackclient.image.v2.image:ShowImage
-    image_set = openstackclient.image.v2.image:SetImage
-    image_unset = openstackclient.image.v2.image:UnsetImage
-    image_stage = openstackclient.image.v2.image:StageImage
-    image_task_show = openstackclient.image.v2.task:ShowTask
-    image_task_list = openstackclient.image.v2.task:ListTask
-    image_import_info = openstackclient.image.v2.info:ImportInfo
-    image_import = openstackclient.image.v2.image:ImportImage
-    image_stores_list = openstackclient.image.v2.image:StoresInfo
-
-    image_metadef_namespace_create = openstackclient.image.v2.metadef_namespaces:CreateMetadefNamespace
-    image_metadef_namespace_delete = openstackclient.image.v2.metadef_namespaces:DeleteMetadefNamespace
-    image_metadef_namespace_list = openstackclient.image.v2.metadef_namespaces:ListMetadefNamespace
-    image_metadef_namespace_set = openstackclient.image.v2.metadef_namespaces:SetMetadefNamespace
-    image_metadef_namespace_show = openstackclient.image.v2.metadef_namespaces:ShowMetadefNamespace
-
-    image_metadef_object_create = openstackclient.image.v2.metadef_objects:CreateMetadefObjects
-    image_metadef_object_show = openstackclient.image.v2.metadef_objects:ShowMetadefObjects
-    image_metadef_object_list = openstackclient.image.v2.metadef_objects:ListMetadefObjects
-    image_metadef_object_delete = openstackclient.image.v2.metadef_objects:DeleteMetadefObject
-    image_metadef_object_update = openstackclient.image.v2.metadef_objects:SetMetadefObject
-    image_metadef_object_property_show = openstackclient.image.v2.metadef_objects:ShowMetadefObjectProperty
-
-    image_metadef_property_create = openstackclient.image.v2.metadef_properties:CreateMetadefProperty
-    image_metadef_property_delete = openstackclient.image.v2.metadef_properties:DeleteMetadefProperty
-    image_metadef_property_list = openstackclient.image.v2.metadef_properties:ListMetadefProperties
-    image_metadef_property_set = openstackclient.image.v2.metadef_properties:SetMetadefProperty
-    image_metadef_property_show = openstackclient.image.v2.metadef_properties:ShowMetadefProperty
-
-    image_metadef_resource_type_list = openstackclient.image.v2.metadef_resource_types:ListMetadefResourceTypes
-    image_metadef_resource_type_association_create = openstackclient.image.v2.metadef_resource_type_association:CreateMetadefResourceTypeAssociation
-    image_metadef_resource_type_association_delete = openstackclient.image.v2.metadef_resource_type_association:DeleteMetadefResourceTypeAssociation
-    image_metadef_resource_type_association_list = openstackclient.image.v2.metadef_resource_type_association:ListMetadefResourceTypeAssociations
-
-    cached_image_list = openstackclient.image.v2.cache:ListCachedImage
-    cached_image_queue = openstackclient.image.v2.cache:QueueCachedImage
-    cached_image_delete = openstackclient.image.v2.cache:DeleteCachedImage
-    cached_image_clear = openstackclient.image.v2.cache:ClearCachedImage
-
-openstack.network.v2 =
-    address_group_create = openstackclient.network.v2.address_group:CreateAddressGroup
-    address_group_delete = openstackclient.network.v2.address_group:DeleteAddressGroup
-    address_group_list = openstackclient.network.v2.address_group:ListAddressGroup
-    address_group_set = openstackclient.network.v2.address_group:SetAddressGroup
-    address_group_show = openstackclient.network.v2.address_group:ShowAddressGroup
-    address_group_unset = openstackclient.network.v2.address_group:UnsetAddressGroup
-
-    address_scope_create = openstackclient.network.v2.address_scope:CreateAddressScope
-    address_scope_delete = openstackclient.network.v2.address_scope:DeleteAddressScope
-    address_scope_list = openstackclient.network.v2.address_scope:ListAddressScope
-    address_scope_set = openstackclient.network.v2.address_scope:SetAddressScope
-    address_scope_show = openstackclient.network.v2.address_scope:ShowAddressScope
-
-    floating_ip_create = openstackclient.network.v2.floating_ip:CreateFloatingIP
-    floating_ip_delete = openstackclient.network.v2.floating_ip:DeleteFloatingIP
-    floating_ip_list = openstackclient.network.v2.floating_ip:ListFloatingIP
-    floating_ip_set = openstackclient.network.v2.floating_ip:SetFloatingIP
-    floating_ip_show = openstackclient.network.v2.floating_ip:ShowFloatingIP
-    floating_ip_unset = openstackclient.network.v2.floating_ip:UnsetFloatingIP
-
-    floating_ip_pool_list = openstackclient.network.v2.floating_ip_pool:ListFloatingIPPool
-
-    floating_ip_port_forwarding_create = openstackclient.network.v2.floating_ip_port_forwarding:CreateFloatingIPPortForwarding
-    floating_ip_port_forwarding_delete = openstackclient.network.v2.floating_ip_port_forwarding:DeleteFloatingIPPortForwarding
-    floating_ip_port_forwarding_list = openstackclient.network.v2.floating_ip_port_forwarding:ListFloatingIPPortForwarding
-    floating_ip_port_forwarding_set = openstackclient.network.v2.floating_ip_port_forwarding:SetFloatingIPPortForwarding
-    floating_ip_port_forwarding_show = openstackclient.network.v2.floating_ip_port_forwarding:ShowFloatingIPPortForwarding
-
-    ip_availability_list = openstackclient.network.v2.ip_availability:ListIPAvailability
-    ip_availability_show = openstackclient.network.v2.ip_availability:ShowIPAvailability
-
-    local_ip_create = openstackclient.network.v2.local_ip:CreateLocalIP
-    local_ip_delete = openstackclient.network.v2.local_ip:DeleteLocalIP
-    local_ip_list = openstackclient.network.v2.local_ip:ListLocalIP
-    local_ip_set = openstackclient.network.v2.local_ip:SetLocalIP
-    local_ip_show = openstackclient.network.v2.local_ip:ShowLocalIP
-
-    local_ip_association_create = openstackclient.network.v2.local_ip_association:CreateLocalIPAssociation
-    local_ip_association_delete = openstackclient.network.v2.local_ip_association:DeleteLocalIPAssociation
-    local_ip_association_list = openstackclient.network.v2.local_ip_association:ListLocalIPAssociation
-
-    network_agent_add_network = openstackclient.network.v2.network_agent:AddNetworkToAgent
-    network_agent_add_router = openstackclient.network.v2.network_agent:AddRouterToAgent
-    network_agent_delete = openstackclient.network.v2.network_agent:DeleteNetworkAgent
-    network_agent_list = openstackclient.network.v2.network_agent:ListNetworkAgent
-    network_agent_remove_network = openstackclient.network.v2.network_agent:RemoveNetworkFromAgent
-    network_agent_remove_router = openstackclient.network.v2.network_agent:RemoveRouterFromAgent
-    network_agent_set = openstackclient.network.v2.network_agent:SetNetworkAgent
-    network_agent_show = openstackclient.network.v2.network_agent:ShowNetworkAgent
-
-    network_auto_allocated_topology_create = openstackclient.network.v2.network_auto_allocated_topology:CreateAutoAllocatedTopology
-    network_auto_allocated_topology_delete = openstackclient.network.v2.network_auto_allocated_topology:DeleteAutoAllocatedTopology
-
-    network_flavor_add_profile = openstackclient.network.v2.network_flavor:AddNetworkFlavorToProfile
-    network_flavor_create = openstackclient.network.v2.network_flavor:CreateNetworkFlavor
-    network_flavor_delete = openstackclient.network.v2.network_flavor:DeleteNetworkFlavor
-    network_flavor_list = openstackclient.network.v2.network_flavor:ListNetworkFlavor
-    network_flavor_remove_profile = openstackclient.network.v2.network_flavor:RemoveNetworkFlavorFromProfile
-    network_flavor_set = openstackclient.network.v2.network_flavor:SetNetworkFlavor
-    network_flavor_show = openstackclient.network.v2.network_flavor:ShowNetworkFlavor
-
-    network_flavor_profile_create = openstackclient.network.v2.network_flavor_profile:CreateNetworkFlavorProfile
-    network_flavor_profile_delete = openstackclient.network.v2.network_flavor_profile:DeleteNetworkFlavorProfile
-    network_flavor_profile_list = openstackclient.network.v2.network_flavor_profile:ListNetworkFlavorProfile
-    network_flavor_profile_set = openstackclient.network.v2.network_flavor_profile:SetNetworkFlavorProfile
-    network_flavor_profile_show = openstackclient.network.v2.network_flavor_profile:ShowNetworkFlavorProfile
-
-    network_create = openstackclient.network.v2.network:CreateNetwork
-    network_delete = openstackclient.network.v2.network:DeleteNetwork
-    network_list = openstackclient.network.v2.network:ListNetwork
-    network_set = openstackclient.network.v2.network:SetNetwork
-    network_show = openstackclient.network.v2.network:ShowNetwork
-    network_unset = openstackclient.network.v2.network:UnsetNetwork
-
-    network_l3_conntrack_helper_create = openstackclient.network.v2.l3_conntrack_helper:CreateConntrackHelper
-    network_l3_conntrack_helper_delete = openstackclient.network.v2.l3_conntrack_helper:DeleteConntrackHelper
-    network_l3_conntrack_helper_list = openstackclient.network.v2.l3_conntrack_helper:ListConntrackHelper
-    network_l3_conntrack_helper_set = openstackclient.network.v2.l3_conntrack_helper:SetConntrackHelper
-    network_l3_conntrack_helper_show = openstackclient.network.v2.l3_conntrack_helper:ShowConntrackHelper
-
-    network_meter_create = openstackclient.network.v2.network_meter:CreateMeter
-    network_meter_delete = openstackclient.network.v2.network_meter:DeleteMeter
-    network_meter_list = openstackclient.network.v2.network_meter:ListMeter
-    network_meter_show = openstackclient.network.v2.network_meter:ShowMeter
-
-    network_meter_rule_create = openstackclient.network.v2.network_meter_rule:CreateMeterRule
-    network_meter_rule_delete = openstackclient.network.v2.network_meter_rule:DeleteMeterRule
-    network_meter_rule_list = openstackclient.network.v2.network_meter_rule:ListMeterRule
-    network_meter_rule_show = openstackclient.network.v2.network_meter_rule:ShowMeterRule
-
-    network_qos_policy_create = openstackclient.network.v2.network_qos_policy:CreateNetworkQosPolicy
-    network_qos_policy_delete = openstackclient.network.v2.network_qos_policy:DeleteNetworkQosPolicy
-    network_qos_policy_list = openstackclient.network.v2.network_qos_policy:ListNetworkQosPolicy
-    network_qos_policy_set = openstackclient.network.v2.network_qos_policy:SetNetworkQosPolicy
-    network_qos_policy_show = openstackclient.network.v2.network_qos_policy:ShowNetworkQosPolicy
-
-    network_qos_rule_create = openstackclient.network.v2.network_qos_rule:CreateNetworkQosRule
-    network_qos_rule_delete = openstackclient.network.v2.network_qos_rule:DeleteNetworkQosRule
-    network_qos_rule_list = openstackclient.network.v2.network_qos_rule:ListNetworkQosRule
-    network_qos_rule_set = openstackclient.network.v2.network_qos_rule:SetNetworkQosRule
-    network_qos_rule_show = openstackclient.network.v2.network_qos_rule:ShowNetworkQosRule
-
-    network_qos_rule_type_list = openstackclient.network.v2.network_qos_rule_type:ListNetworkQosRuleType
-    network_qos_rule_type_show = openstackclient.network.v2.network_qos_rule_type:ShowNetworkQosRuleType
-
-    network_rbac_create = openstackclient.network.v2.network_rbac:CreateNetworkRBAC
-    network_rbac_delete = openstackclient.network.v2.network_rbac:DeleteNetworkRBAC
-    network_rbac_list = openstackclient.network.v2.network_rbac:ListNetworkRBAC
-    network_rbac_set = openstackclient.network.v2.network_rbac:SetNetworkRBAC
-    network_rbac_show = openstackclient.network.v2.network_rbac:ShowNetworkRBAC
-
-    network_segment_create = openstackclient.network.v2.network_segment:CreateNetworkSegment
-    network_segment_delete = openstackclient.network.v2.network_segment:DeleteNetworkSegment
-    network_segment_list = openstackclient.network.v2.network_segment:ListNetworkSegment
-    network_segment_set = openstackclient.network.v2.network_segment:SetNetworkSegment
-    network_segment_show = openstackclient.network.v2.network_segment:ShowNetworkSegment
-
-    network_segment_range_create = openstackclient.network.v2.network_segment_range:CreateNetworkSegmentRange
-    network_segment_range_delete = openstackclient.network.v2.network_segment_range:DeleteNetworkSegmentRange
-    network_segment_range_list = openstackclient.network.v2.network_segment_range:ListNetworkSegmentRange
-    network_segment_range_set = openstackclient.network.v2.network_segment_range:SetNetworkSegmentRange
-    network_segment_range_show = openstackclient.network.v2.network_segment_range:ShowNetworkSegmentRange
-
-    network_service_provider_list = openstackclient.network.v2.network_service_provider:ListNetworkServiceProvider
-
-    network_subport_list = openstackclient.network.v2.network_trunk:ListNetworkSubport
-    network_trunk_create = openstackclient.network.v2.network_trunk:CreateNetworkTrunk
-    network_trunk_delete = openstackclient.network.v2.network_trunk:DeleteNetworkTrunk
-    network_trunk_list = openstackclient.network.v2.network_trunk:ListNetworkTrunk
-    network_trunk_set = openstackclient.network.v2.network_trunk:SetNetworkTrunk
-    network_trunk_show = openstackclient.network.v2.network_trunk:ShowNetworkTrunk
-    network_trunk_unset = openstackclient.network.v2.network_trunk:UnsetNetworkTrunk
-
-    port_create = openstackclient.network.v2.port:CreatePort
-    port_delete = openstackclient.network.v2.port:DeletePort
-    port_list = openstackclient.network.v2.port:ListPort
-    port_set = openstackclient.network.v2.port:SetPort
-    port_show = openstackclient.network.v2.port:ShowPort
-    port_unset = openstackclient.network.v2.port:UnsetPort
-
-    router_add_gateway = openstackclient.network.v2.router:AddGatewayToRouter
-    router_add_port = openstackclient.network.v2.router:AddPortToRouter
-    router_add_route = openstackclient.network.v2.router:AddExtraRoutesToRouter
-    router_add_subnet = openstackclient.network.v2.router:AddSubnetToRouter
-    router_create = openstackclient.network.v2.router:CreateRouter
-    router_delete = openstackclient.network.v2.router:DeleteRouter
-    router_list = openstackclient.network.v2.router:ListRouter
-    router_remove_gateway = openstackclient.network.v2.router:RemoveGatewayFromRouter
-    router_remove_port = openstackclient.network.v2.router:RemovePortFromRouter
-    router_remove_route = openstackclient.network.v2.router:RemoveExtraRoutesFromRouter
-    router_remove_subnet = openstackclient.network.v2.router:RemoveSubnetFromRouter
-    router_set = openstackclient.network.v2.router:SetRouter
-    router_show = openstackclient.network.v2.router:ShowRouter
-    router_unset = openstackclient.network.v2.router:UnsetRouter
-
-    router_ndp_proxy_create = openstackclient.network.v2.ndp_proxy:CreateNDPProxy
-    router_ndp_proxy_delete = openstackclient.network.v2.ndp_proxy:DeleteNDPProxy
-    router_ndp_proxy_list = openstackclient.network.v2.ndp_proxy:ListNDPProxy
-    router_ndp_proxy_set = openstackclient.network.v2.ndp_proxy:SetNDPProxy
-    router_ndp_proxy_show = openstackclient.network.v2.ndp_proxy:ShowNDPProxy
-
-    security_group_create = openstackclient.network.v2.security_group:CreateSecurityGroup
-    security_group_delete = openstackclient.network.v2.security_group:DeleteSecurityGroup
-    security_group_list = openstackclient.network.v2.security_group:ListSecurityGroup
-    security_group_set = openstackclient.network.v2.security_group:SetSecurityGroup
-    security_group_show = openstackclient.network.v2.security_group:ShowSecurityGroup
-    security_group_unset = openstackclient.network.v2.security_group:UnsetSecurityGroup
-
-    security_group_rule_create = openstackclient.network.v2.security_group_rule:CreateSecurityGroupRule
-    security_group_rule_delete = openstackclient.network.v2.security_group_rule:DeleteSecurityGroupRule
-    security_group_rule_list = openstackclient.network.v2.security_group_rule:ListSecurityGroupRule
-    security_group_rule_show = openstackclient.network.v2.security_group_rule:ShowSecurityGroupRule
-
-    default_security_group_rule_create = openstackclient.network.v2.default_security_group_rule:CreateDefaultSecurityGroupRule
-    default_security_group_rule_delete = openstackclient.network.v2.default_security_group_rule:DeleteDefaultSecurityGroupRule
-    default_security_group_rule_list = openstackclient.network.v2.default_security_group_rule:ListDefaultSecurityGroupRule
-    default_security_group_rule_show = openstackclient.network.v2.default_security_group_rule:ShowDefaultSecurityGroupRule
-
-    subnet_create = openstackclient.network.v2.subnet:CreateSubnet
-    subnet_delete = openstackclient.network.v2.subnet:DeleteSubnet
-    subnet_list = openstackclient.network.v2.subnet:ListSubnet
-    subnet_set = openstackclient.network.v2.subnet:SetSubnet
-    subnet_show = openstackclient.network.v2.subnet:ShowSubnet
-    subnet_unset = openstackclient.network.v2.subnet:UnsetSubnet
-
-    subnet_pool_create = openstackclient.network.v2.subnet_pool:CreateSubnetPool
-    subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool
-    subnet_pool_list = openstackclient.network.v2.subnet_pool:ListSubnetPool
-    subnet_pool_set = openstackclient.network.v2.subnet_pool:SetSubnetPool
-    subnet_pool_show = openstackclient.network.v2.subnet_pool:ShowSubnetPool
-    subnet_pool_unset = openstackclient.network.v2.subnet_pool:UnsetSubnetPool
-
-openstack.object_store.v1 =
-    object_store_account_set = openstackclient.object.v1.account:SetAccount
-    object_store_account_show = openstackclient.object.v1.account:ShowAccount
-    object_store_account_unset = openstackclient.object.v1.account:UnsetAccount
-    container_create = openstackclient.object.v1.container:CreateContainer
-    container_delete = openstackclient.object.v1.container:DeleteContainer
-    container_list = openstackclient.object.v1.container:ListContainer
-    container_save = openstackclient.object.v1.container:SaveContainer
-    container_set = openstackclient.object.v1.container:SetContainer
-    container_show = openstackclient.object.v1.container:ShowContainer
-    container_unset = openstackclient.object.v1.container:UnsetContainer
-    object_create = openstackclient.object.v1.object:CreateObject
-    object_delete = openstackclient.object.v1.object:DeleteObject
-    object_list = openstackclient.object.v1.object:ListObject
-    object_save = openstackclient.object.v1.object:SaveObject
-    object_set = openstackclient.object.v1.object:SetObject
-    object_show = openstackclient.object.v1.object:ShowObject
-    object_unset = openstackclient.object.v1.object:UnsetObject
-
-openstack.volume.v1 =
-    volume_create = openstackclient.volume.v1.volume:CreateVolume
-    volume_delete = openstackclient.volume.v1.volume:DeleteVolume
-    volume_list = openstackclient.volume.v1.volume:ListVolume
-    volume_migrate = openstackclient.volume.v1.volume:MigrateVolume
-    volume_set = openstackclient.volume.v1.volume:SetVolume
-    volume_show = openstackclient.volume.v1.volume:ShowVolume
-    volume_unset = openstackclient.volume.v1.volume:UnsetVolume
-
-    volume_backup_create = openstackclient.volume.v1.volume_backup:CreateVolumeBackup
-    volume_backup_delete = openstackclient.volume.v1.volume_backup:DeleteVolumeBackup
-    volume_backup_list = openstackclient.volume.v1.volume_backup:ListVolumeBackup
-    volume_backup_restore = openstackclient.volume.v1.volume_backup:RestoreVolumeBackup
-    volume_backup_show = openstackclient.volume.v1.volume_backup:ShowVolumeBackup
-
-    volume_snapshot_create = openstackclient.volume.v1.volume_snapshot:CreateVolumeSnapshot
-    volume_snapshot_delete = openstackclient.volume.v1.volume_snapshot:DeleteVolumeSnapshot
-    volume_snapshot_list = openstackclient.volume.v1.volume_snapshot:ListVolumeSnapshot
-    volume_snapshot_set = openstackclient.volume.v1.volume_snapshot:SetVolumeSnapshot
-    volume_snapshot_show = openstackclient.volume.v1.volume_snapshot:ShowVolumeSnapshot
-    volume_snapshot_unset = openstackclient.volume.v1.volume_snapshot:UnsetVolumeSnapshot
-
-    volume_type_create = openstackclient.volume.v1.volume_type:CreateVolumeType
-    volume_type_delete = openstackclient.volume.v1.volume_type:DeleteVolumeType
-    volume_type_list = openstackclient.volume.v1.volume_type:ListVolumeType
-    volume_type_set = openstackclient.volume.v1.volume_type:SetVolumeType
-    volume_type_show = openstackclient.volume.v1.volume_type:ShowVolumeType
-    volume_type_unset = openstackclient.volume.v1.volume_type:UnsetVolumeType
-
-    volume_qos_associate = openstackclient.volume.v1.qos_specs:AssociateQos
-    volume_qos_create = openstackclient.volume.v1.qos_specs:CreateQos
-    volume_qos_delete = openstackclient.volume.v1.qos_specs:DeleteQos
-    volume_qos_disassociate = openstackclient.volume.v1.qos_specs:DisassociateQos
-    volume_qos_list = openstackclient.volume.v1.qos_specs:ListQos
-    volume_qos_set = openstackclient.volume.v1.qos_specs:SetQos
-    volume_qos_show = openstackclient.volume.v1.qos_specs:ShowQos
-    volume_qos_unset = openstackclient.volume.v1.qos_specs:UnsetQos
-
-    volume_service_list = openstackclient.volume.v1.service:ListService
-    volume_service_set = openstackclient.volume.v1.service:SetService
-
-    volume_transfer_request_accept = openstackclient.volume.v1.volume_transfer_request:AcceptTransferRequest
-    volume_transfer_request_create = openstackclient.volume.v1.volume_transfer_request:CreateTransferRequest
-    volume_transfer_request_delete = openstackclient.volume.v1.volume_transfer_request:DeleteTransferRequest
-    volume_transfer_request_list = openstackclient.volume.v1.volume_transfer_request:ListTransferRequest
-    volume_transfer_request_show = openstackclient.volume.v1.volume_transfer_request:ShowTransferRequest
-
-openstack.volume.v2 =
-    consistency_group_add_volume = openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup
-    consistency_group_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
-    consistency_group_delete = openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup
-    consistency_group_list = openstackclient.volume.v2.consistency_group:ListConsistencyGroup
-    consistency_group_remove_volume = openstackclient.volume.v2.consistency_group:RemoveVolumeFromConsistencyGroup
-    consistency_group_set = openstackclient.volume.v2.consistency_group:SetConsistencyGroup
-    consistency_group_show = openstackclient.volume.v2.consistency_group:ShowConsistencyGroup
-
-    consistency_group_snapshot_create = openstackclient.volume.v2.consistency_group_snapshot:CreateConsistencyGroupSnapshot
-    consistency_group_snapshot_delete = openstackclient.volume.v2.consistency_group_snapshot:DeleteConsistencyGroupSnapshot
-    consistency_group_snapshot_list = openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot
-    consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot
-
-    volume_create = openstackclient.volume.v2.volume:CreateVolume
-    volume_delete = openstackclient.volume.v2.volume:DeleteVolume
-    volume_list = openstackclient.volume.v2.volume:ListVolume
-    volume_migrate = openstackclient.volume.v2.volume:MigrateVolume
-    volume_set = openstackclient.volume.v2.volume:SetVolume
-    volume_show = openstackclient.volume.v2.volume:ShowVolume
-    volume_unset = openstackclient.volume.v2.volume:UnsetVolume
-
-    volume_backup_create = openstackclient.volume.v2.volume_backup:CreateVolumeBackup
-    volume_backup_delete = openstackclient.volume.v2.volume_backup:DeleteVolumeBackup
-    volume_backup_list = openstackclient.volume.v2.volume_backup:ListVolumeBackup
-    volume_backup_restore = openstackclient.volume.v2.volume_backup:RestoreVolumeBackup
-    volume_backup_set = openstackclient.volume.v2.volume_backup:SetVolumeBackup
-    volume_backup_show = openstackclient.volume.v2.volume_backup:ShowVolumeBackup
-
-    volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
-    volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
-
-    volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability
-    volume_backend_pool_list = openstackclient.volume.v2.volume_backend:ListPool
-
-    volume_host_failover = openstackclient.volume.v2.volume_host:FailoverVolumeHost
-    volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost
-
-    volume_snapshot_create = openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot
-    volume_snapshot_delete = openstackclient.volume.v2.volume_snapshot:DeleteVolumeSnapshot
-    volume_snapshot_list = openstackclient.volume.v2.volume_snapshot:ListVolumeSnapshot
-    volume_snapshot_set = openstackclient.volume.v2.volume_snapshot:SetVolumeSnapshot
-    volume_snapshot_show = openstackclient.volume.v2.volume_snapshot:ShowVolumeSnapshot
-    volume_snapshot_unset = openstackclient.volume.v2.volume_snapshot:UnsetVolumeSnapshot
-
-    volume_type_create = openstackclient.volume.v2.volume_type:CreateVolumeType
-    volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType
-    volume_type_list = openstackclient.volume.v2.volume_type:ListVolumeType
-    volume_type_set = openstackclient.volume.v2.volume_type:SetVolumeType
-    volume_type_show = openstackclient.volume.v2.volume_type:ShowVolumeType
-    volume_type_unset = openstackclient.volume.v2.volume_type:UnsetVolumeType
-
-    volume_qos_associate = openstackclient.volume.v2.qos_specs:AssociateQos
-    volume_qos_create = openstackclient.volume.v2.qos_specs:CreateQos
-    volume_qos_delete = openstackclient.volume.v2.qos_specs:DeleteQos
-    volume_qos_disassociate = openstackclient.volume.v2.qos_specs:DisassociateQos
-    volume_qos_list = openstackclient.volume.v2.qos_specs:ListQos
-    volume_qos_set = openstackclient.volume.v2.qos_specs:SetQos
-    volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
-    volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
-
-    volume_service_list = openstackclient.volume.v2.service:ListService
-    volume_service_set = openstackclient.volume.v2.service:SetService
-
-    volume_transfer_request_accept = openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest
-    volume_transfer_request_create = openstackclient.volume.v2.volume_transfer_request:CreateTransferRequest
-    volume_transfer_request_delete = openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest
-    volume_transfer_request_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest
-    volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest
-
-openstack.volume.v3 =
-    consistency_group_add_volume = openstackclient.volume.v2.consistency_group:AddVolumeToConsistencyGroup
-    consistency_group_create = openstackclient.volume.v2.consistency_group:CreateConsistencyGroup
-    consistency_group_delete = openstackclient.volume.v2.consistency_group:DeleteConsistencyGroup
-    consistency_group_list = openstackclient.volume.v2.consistency_group:ListConsistencyGroup
-    consistency_group_remove_volume = openstackclient.volume.v2.consistency_group:RemoveVolumeFromConsistencyGroup
-    consistency_group_set = openstackclient.volume.v2.consistency_group:SetConsistencyGroup
-    consistency_group_show = openstackclient.volume.v2.consistency_group:ShowConsistencyGroup
-
-    consistency_group_snapshot_create = openstackclient.volume.v2.consistency_group_snapshot:CreateConsistencyGroupSnapshot
-    consistency_group_snapshot_delete = openstackclient.volume.v2.consistency_group_snapshot:DeleteConsistencyGroupSnapshot
-    consistency_group_snapshot_list = openstackclient.volume.v2.consistency_group_snapshot:ListConsistencyGroupSnapshot
-    consistency_group_snapshot_show = openstackclient.volume.v2.consistency_group_snapshot:ShowConsistencyGroupSnapshot
-
-    volume_create = openstackclient.volume.v3.volume:CreateVolume
-    volume_delete = openstackclient.volume.v3.volume:DeleteVolume
-    volume_list = openstackclient.volume.v3.volume:ListVolume
-    volume_migrate = openstackclient.volume.v3.volume:MigrateVolume
-    volume_set = openstackclient.volume.v3.volume:SetVolume
-    volume_show = openstackclient.volume.v3.volume:ShowVolume
-    volume_unset = openstackclient.volume.v3.volume:UnsetVolume
-
-    volume_attachment_create = openstackclient.volume.v3.volume_attachment:CreateVolumeAttachment
-    volume_attachment_delete = openstackclient.volume.v3.volume_attachment:DeleteVolumeAttachment
-    volume_attachment_list = openstackclient.volume.v3.volume_attachment:ListVolumeAttachment
-    volume_attachment_complete = openstackclient.volume.v3.volume_attachment:CompleteVolumeAttachment
-    volume_attachment_set = openstackclient.volume.v3.volume_attachment:SetVolumeAttachment
-    volume_attachment_show = openstackclient.volume.v3.volume_attachment:ShowVolumeAttachment
-
-    volume_backup_create = openstackclient.volume.v3.volume_backup:CreateVolumeBackup
-    volume_backup_delete = openstackclient.volume.v3.volume_backup:DeleteVolumeBackup
-    volume_backup_list = openstackclient.volume.v3.volume_backup:ListVolumeBackup
-    volume_backup_restore = openstackclient.volume.v3.volume_backup:RestoreVolumeBackup
-    volume_backup_set = openstackclient.volume.v3.volume_backup:SetVolumeBackup
-    volume_backup_unset = openstackclient.volume.v3.volume_backup:UnsetVolumeBackup
-    volume_backup_show = openstackclient.volume.v3.volume_backup:ShowVolumeBackup
-
-    volume_backend_capability_show = openstackclient.volume.v2.volume_backend:ShowCapability
-    volume_backend_pool_list = openstackclient.volume.v2.volume_backend:ListPool
-
-    volume_backup_record_export = openstackclient.volume.v2.backup_record:ExportBackupRecord
-    volume_backup_record_import = openstackclient.volume.v2.backup_record:ImportBackupRecord
-
-    volume_group_create = openstackclient.volume.v3.volume_group:CreateVolumeGroup
-    volume_group_delete = openstackclient.volume.v3.volume_group:DeleteVolumeGroup
-    volume_group_list = openstackclient.volume.v3.volume_group:ListVolumeGroup
-    volume_group_failover = openstackclient.volume.v3.volume_group:FailoverVolumeGroup
-    volume_group_set = openstackclient.volume.v3.volume_group:SetVolumeGroup
-    volume_group_show = openstackclient.volume.v3.volume_group:ShowVolumeGroup
-
-    volume_group_snapshot_create = openstackclient.volume.v3.volume_group_snapshot:CreateVolumeGroupSnapshot
-    volume_group_snapshot_delete = openstackclient.volume.v3.volume_group_snapshot:DeleteVolumeGroupSnapshot
-    volume_group_snapshot_list = openstackclient.volume.v3.volume_group_snapshot:ListVolumeGroupSnapshot
-    volume_group_snapshot_show = openstackclient.volume.v3.volume_group_snapshot:ShowVolumeGroupSnapshot
-
-    volume_group_type_create = openstackclient.volume.v3.volume_group_type:CreateVolumeGroupType
-    volume_group_type_delete = openstackclient.volume.v3.volume_group_type:DeleteVolumeGroupType
-    volume_group_type_list = openstackclient.volume.v3.volume_group_type:ListVolumeGroupType
-    volume_group_type_set = openstackclient.volume.v3.volume_group_type:SetVolumeGroupType
-    volume_group_type_show = openstackclient.volume.v3.volume_group_type:ShowVolumeGroupType
-
-    volume_host_set = openstackclient.volume.v2.volume_host:SetVolumeHost
-
-    volume_message_delete = openstackclient.volume.v3.volume_message:DeleteMessage
-    volume_message_list = openstackclient.volume.v3.volume_message:ListMessages
-    volume_message_show = openstackclient.volume.v3.volume_message:ShowMessage
-
-    block_storage_cluster_list = openstackclient.volume.v3.block_storage_cluster:ListBlockStorageCluster
-    block_storage_cluster_set = openstackclient.volume.v3.block_storage_cluster:SetBlockStorageCluster
-    block_storage_cluster_show = openstackclient.volume.v3.block_storage_cluster:ShowBlockStorageCluster
-    block_storage_resource_filter_list = openstackclient.volume.v3.block_storage_resource_filter:ListBlockStorageResourceFilter
-    block_storage_resource_filter_show = openstackclient.volume.v3.block_storage_resource_filter:ShowBlockStorageResourceFilter
-
-    volume_snapshot_create = openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot
-    volume_snapshot_delete = openstackclient.volume.v3.volume_snapshot:DeleteVolumeSnapshot
-    volume_snapshot_list = openstackclient.volume.v2.volume_snapshot:ListVolumeSnapshot
-    volume_snapshot_set = openstackclient.volume.v2.volume_snapshot:SetVolumeSnapshot
-    volume_snapshot_show = openstackclient.volume.v2.volume_snapshot:ShowVolumeSnapshot
-    volume_snapshot_unset = openstackclient.volume.v2.volume_snapshot:UnsetVolumeSnapshot
-
-    volume_type_create = openstackclient.volume.v3.volume_type:CreateVolumeType
-    volume_type_delete = openstackclient.volume.v3.volume_type:DeleteVolumeType
-    volume_type_list = openstackclient.volume.v3.volume_type:ListVolumeType
-    volume_type_set = openstackclient.volume.v3.volume_type:SetVolumeType
-    volume_type_show = openstackclient.volume.v3.volume_type:ShowVolumeType
-    volume_type_unset = openstackclient.volume.v3.volume_type:UnsetVolumeType
-
-    volume_qos_associate = openstackclient.volume.v2.qos_specs:AssociateQos
-    volume_qos_create = openstackclient.volume.v2.qos_specs:CreateQos
-    volume_qos_delete = openstackclient.volume.v2.qos_specs:DeleteQos
-    volume_qos_disassociate = openstackclient.volume.v2.qos_specs:DisassociateQos
-    volume_qos_list = openstackclient.volume.v2.qos_specs:ListQos
-    volume_qos_set = openstackclient.volume.v2.qos_specs:SetQos
-    volume_qos_show = openstackclient.volume.v2.qos_specs:ShowQos
-    volume_qos_unset = openstackclient.volume.v2.qos_specs:UnsetQos
-
-    volume_service_list = openstackclient.volume.v3.service:ListService
-    volume_service_set = openstackclient.volume.v2.service:SetService
-
-    volume_transfer_request_accept = openstackclient.volume.v3.volume_transfer_request:AcceptTransferRequest
-    volume_transfer_request_create = openstackclient.volume.v3.volume_transfer_request:CreateTransferRequest
-    volume_transfer_request_delete = openstackclient.volume.v3.volume_transfer_request:DeleteTransferRequest
-    volume_transfer_request_list = openstackclient.volume.v3.volume_transfer_request:ListTransferRequest
-    volume_transfer_request_show = openstackclient.volume.v3.volume_transfer_request:ShowTransferRequest
-
-    volume_summary = openstackclient.volume.v3.volume:VolumeSummary
-    volume_revert = openstackclient.volume.v3.volume:VolumeRevertToSnapshot
-    block_storage_log_level_list = openstackclient.volume.v3.block_storage_log_level:BlockStorageLogLevelList
-    block_storage_log_level_set = openstackclient.volume.v3.block_storage_log_level:BlockStorageLogLevelSet
-    block_storage_cleanup = openstackclient.volume.v3.block_storage_cleanup:BlockStorageCleanup
-    block_storage_volume_manageable_list = openstackclient.volume.v3.block_storage_manage:BlockStorageManageVolumes
-    block_storage_snapshot_manageable_list = openstackclient.volume.v3.block_storage_manage:BlockStorageManageSnapshots
