diff -pruN 24.0.0-1/README.rst 25.0.0~rc1-1/README.rst
--- 24.0.0-1/README.rst	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/README.rst	2025-09-09 03:44:01.000000000 +0000
@@ -170,7 +170,7 @@ to use the same cache like the example b
     CACHES = {
         'default': {
             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
-            'LOCATION': [u'10.2.100.133:11211', u'10.2.100.134:11211'']
+            'LOCATION': ['10.2.100.133:11211', '10.2.100.134:11211'']
         },
     }
 
@@ -186,6 +186,8 @@ Links:
 
 Trove project: https://opendev.org/openstack/trove/
 
+Trove Documentation: https://docs.openstack.org/trove/latest
+
 Trove at wiki.openstack.org: https://wiki.openstack.org/wiki/Trove
 
 Launchpad project: https://launchpad.net/trove-dashboard
diff -pruN 24.0.0-1/debian/changelog 25.0.0~rc1-1/debian/changelog
--- 24.0.0-1/debian/changelog	2025-04-02 12:21:01.000000000 +0000
+++ 25.0.0~rc1-1/debian/changelog	2025-09-16 08:35:37.000000000 +0000
@@ -1,3 +1,10 @@
+trove-dashboard (25.0.0~rc1-1) experimental; urgency=medium
+
+  * New upstream release.
+  * Fixed (build-)depends for this release.
+
+ -- Thomas Goirand <zigo@debian.org>  Tue, 16 Sep 2025 10:35:37 +0200
+
 trove-dashboard (24.0.0-1) unstable; urgency=medium
 
   * New upstream release.
diff -pruN 24.0.0-1/debian/control 25.0.0~rc1-1/debian/control
--- 24.0.0-1/debian/control	2025-04-02 12:21:01.000000000 +0000
+++ 25.0.0~rc1-1/debian/control	2025-09-16 08:35:37.000000000 +0000
@@ -14,7 +14,7 @@ Build-Depends:
  python3-setuptools,
  python3-sphinx,
 Build-Depends-Indep:
- openstack-dashboard (>= 3:23.3.0),
+ openstack-dashboard,
  python3-coverage,
  python3-ddt,
  python3-django,
@@ -37,7 +37,7 @@ Homepage: https://opendev.org/openstack/
 Package: python3-trove-dashboard
 Architecture: all
 Depends:
- openstack-dashboard (>= 3:23.3.0),
+ openstack-dashboard,
  python3-django,
  python3-oslo.log,
  python3-pbr,
@@ -45,8 +45,6 @@ Depends:
  python3-troveclient,
  ${misc:Depends},
  ${python3:Depends},
-Breaks:
- python3-django-horizon (<< 3:19.2.0-2~),
 Description: Database as a Service for OpenStack - dashboard plugin
  Trove is Database as a Service for Openstack. It's designed to run entirely on
  OpenStack, with the goal of allowing users to quickly and easily utilize the
diff -pruN 24.0.0-1/releasenotes/notes/category-database-renamed-to-databases-in-menu.yaml 25.0.0~rc1-1/releasenotes/notes/category-database-renamed-to-databases-in-menu.yaml
--- 24.0.0-1/releasenotes/notes/category-database-renamed-to-databases-in-menu.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/notes/category-database-renamed-to-databases-in-menu.yaml	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,4 @@
+---
+fixes:
+  - |
+    Database category in menu, renamed in Databases.
diff -pruN 24.0.0-1/releasenotes/notes/dashboard-configuration-id-afd3b51347d54c00.yaml 25.0.0~rc1-1/releasenotes/notes/dashboard-configuration-id-afd3b51347d54c00.yaml
--- 24.0.0-1/releasenotes/notes/dashboard-configuration-id-afd3b51347d54c00.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/notes/dashboard-configuration-id-afd3b51347d54c00.yaml	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Enables dashboard to select a configuration-id.
+    We should select a configuration-id in cluster creation forms because we
+    can select a configuration id when creating a database instance.
diff -pruN 24.0.0-1/releasenotes/notes/remove-py38-24fabe105ecd0add.yaml 25.0.0~rc1-1/releasenotes/notes/remove-py38-24fabe105ecd0add.yaml
--- 24.0.0-1/releasenotes/notes/remove-py38-24fabe105ecd0add.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/notes/remove-py38-24fabe105ecd0add.yaml	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,5 @@
+---
+upgrade:
+  - |
+    Python 3.8 support was dropped. The minimum version of Python now supported
+    is Python 3.9.
diff -pruN 24.0.0-1/releasenotes/notes/support-custom-policies-b7a47657ff92bacb.yaml 25.0.0~rc1-1/releasenotes/notes/support-custom-policies-b7a47657ff92bacb.yaml
--- 24.0.0-1/releasenotes/notes/support-custom-policies-b7a47657ff92bacb.yaml	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/notes/support-custom-policies-b7a47657ff92bacb.yaml	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Dashboard features now check the 'databases' policy file. If the
+    corresponding API is not available to the current user, this UI element
+    will not display or will appear disabled.
diff -pruN 24.0.0-1/releasenotes/source/2023.1.rst 25.0.0~rc1-1/releasenotes/source/2023.1.rst
--- 24.0.0-1/releasenotes/source/2023.1.rst	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/2023.1.rst	2025-09-09 03:44:01.000000000 +0000
@@ -3,4 +3,4 @@
 ===========================
 
 .. release-notes::
-   :branch: stable/2023.1
+   :branch: unmaintained/2023.1
diff -pruN 24.0.0-1/releasenotes/source/2024.2.rst 25.0.0~rc1-1/releasenotes/source/2024.2.rst
--- 24.0.0-1/releasenotes/source/2024.2.rst	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/2024.2.rst	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,6 @@
+===========================
+2024.2 Series Release Notes
+===========================
+
+.. release-notes::
+   :branch: stable/2024.2
diff -pruN 24.0.0-1/releasenotes/source/2025.1.rst 25.0.0~rc1-1/releasenotes/source/2025.1.rst
--- 24.0.0-1/releasenotes/source/2025.1.rst	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/2025.1.rst	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,6 @@
+===========================
+2025.1 Series Release Notes
+===========================
+
+.. release-notes::
+   :branch: stable/2025.1
diff -pruN 24.0.0-1/releasenotes/source/conf.py 25.0.0~rc1-1/releasenotes/source/conf.py
--- 24.0.0-1/releasenotes/source/conf.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/conf.py	2025-09-09 03:44:01.000000000 +0000
@@ -54,9 +54,9 @@ openstackdocs_bug_tag = ''
 master_doc = 'index'
 
 # General information about the project.
-project = u'Trove Dashboard Release Notes'
-copyright = u'2016, Trove developers'
-author = u'Trove developers'
+project = 'Trove Dashboard Release Notes'
+copyright = '2016, Trove developers'
+author = 'Trove developers'
 
 # Release notes are version independent.
 # The short X.Y version.
@@ -126,7 +126,7 @@ html_theme = 'openstackdocs'
 
 # The name for this set of Sphinx documents.
 # "<project> v<release> documentation" by default.
-#html_title = u'Trove Dashboard Release Notes vblah'
+#html_title = 'Trove Dashboard Release Notes vblah'
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
 #html_short_title = None
@@ -230,8 +230,8 @@ latex_elements = {
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'TroveDashboardReleaseNotes.tex', u'Trove Dashboard Release Notes Documentation',
-     u'Trove developers', 'manual'),
+    (master_doc, 'TroveDashboardReleaseNotes.tex', 'Trove Dashboard Release Notes Documentation',
+     'Trove developers', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -260,7 +260,7 @@ latex_documents = [
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    (master_doc, 'trovedashboardreleasenotes', u'Trove Dashboard Release Notes Documentation',
+    (master_doc, 'trovedashboardreleasenotes', 'Trove Dashboard Release Notes Documentation',
      [author], 1)
 ]
 
@@ -274,7 +274,7 @@ man_pages = [
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'TroveDashboardReleaseNotes', u'Trove Dashboard Release Notes Documentation',
+    (master_doc, 'TroveDashboardReleaseNotes', 'Trove Dashboard Release Notes Documentation',
      author, 'TroveDashboardReleaseNotes', 'One line description of project.',
      'Miscellaneous'),
 ]
diff -pruN 24.0.0-1/releasenotes/source/index.rst 25.0.0~rc1-1/releasenotes/source/index.rst
--- 24.0.0-1/releasenotes/source/index.rst	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/index.rst	2025-09-09 03:44:01.000000000 +0000
@@ -8,6 +8,8 @@ Contents:
    :maxdepth: 2
 
    unreleased
+   2025.1
+   2024.2
    2024.1
    2023.2
    2023.1
diff -pruN 24.0.0-1/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po 25.0.0~rc1-1/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
--- 24.0.0-1/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po	2025-09-09 03:44:01.000000000 +0000
@@ -5,15 +5,16 @@
 # Andi Chandler <andi@gowling.com>, 2020. #zanata
 # Andi Chandler <andi@gowling.com>, 2022. #zanata
 # Andi Chandler <andi@gowling.com>, 2023. #zanata
+# Andi Chandler <andi@gowling.com>, 2024. #zanata
 msgid ""
 msgstr ""
 "Project-Id-Version: Trove Dashboard Release Notes\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-03-06 11:17+0000\n"
+"POT-Creation-Date: 2024-03-18 04:05+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2023-05-09 12:17+0000\n"
+"PO-Revision-Date: 2024-04-18 12:28+0000\n"
 "Last-Translator: Andi Chandler <andi@gowling.com>\n"
 "Language-Team: English (United Kingdom)\n"
 "Language: en_GB\n"
@@ -38,6 +39,12 @@ msgstr "19.0.0"
 msgid "2023.1 Series Release Notes"
 msgstr "2023.1 Series Release Notes"
 
+msgid "2023.2 Series Release Notes"
+msgstr "2023.2 Series Release Notes"
+
+msgid "2024.1 Series Release Notes"
+msgstr "2024.1 Series Release Notes"
+
 msgid "7.0.0"
 msgstr "7.0.0"
 
diff -pruN 24.0.0-1/releasenotes/source/locale/ru/LC_MESSAGES/releasenotes.po 25.0.0~rc1-1/releasenotes/source/locale/ru/LC_MESSAGES/releasenotes.po
--- 24.0.0-1/releasenotes/source/locale/ru/LC_MESSAGES/releasenotes.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/locale/ru/LC_MESSAGES/releasenotes.po	2025-09-09 03:44:01.000000000 +0000
@@ -1,20 +1,55 @@
 # Alexander <ainikitenkov@gmail.com>, 2016. #zanata
 # Artem <amikhalev90@gmail.com>, 2017. #zanata
+# Dmitriy Chubinidze <dcu995@gmail.com>, 2025. #zanata
+# Ivan Anfimov <lazekteam@gmail.com>, 2025. #zanata
 msgid ""
 msgstr ""
 "Project-Id-Version: Trove Dashboard Release Notes\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-03-06 11:17+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2017-01-23 12:49+0000\n"
-"Last-Translator: Artem <amikhalev90@gmail.com>\n"
+"PO-Revision-Date: 2025-09-08 09:57+0000\n"
+"Last-Translator: Ivan Anfimov <lazekteam@gmail.com>\n"
 "Language-Team: Russian\n"
 "Language: ru\n"
 "X-Generator: Zanata 4.3.3\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+
+msgid "10.0.0"
+msgstr "10.0.0"
+
+msgid "11.0.0"
+msgstr "11.0.0"
+
+msgid "14.0.0"
+msgstr "14.0.0"
+
+msgid "16.0.0"
+msgstr "16.0.0"
+
+msgid "19.0.0"
+msgstr "19.0.0"
+
+msgid "2023.1 Series Release Notes"
+msgstr "Примечания к выпуску 2023.1"
+
+msgid "2023.2 Series Release Notes"
+msgstr "Примечания к выпуску 2023.2"
+
+msgid "2024.1 Series Release Notes"
+msgstr "Примечания к выпуску 2024.1"
+
+msgid "2024.2 Series Release Notes"
+msgstr "Примечания к выпуску 2024.2"
+
+msgid "2025.1 Series Release Notes"
+msgstr "Примечания к выпуску 2025.1"
+
+msgid "24.0.0-24"
+msgstr "24.0.0-24"
 
 msgid "7.0.0"
 msgstr "7.0.0"
@@ -25,9 +60,49 @@ msgstr "7.0.0.0b2"
 msgid "7.0.0.0rc1"
 msgstr "7.0.0.0rc1"
 
+msgid "8.0.0"
+msgstr "8.0.0"
+
+msgid "8.0.0.0b3"
+msgstr "8.0.0.0b3"
+
 msgid ":ref:`search`"
 msgstr ":ref:`search`"
 
+msgid "Added ability to update allowed_cidr for an existing instance."
+msgstr ""
+"Добавлена ​​возможность обновления allowed_cidr для существующего инстанса."
+
+msgid ""
+"Added support for logging features in the dashboard. This includes listing "
+"logs that can be retrieved and viewing, publishing and stop collection of "
+"log contents."
+msgstr ""
+"Добавлена ​​поддержка функций ведения логирования в панели управления. Это "
+"включает в себя список логов, которые можно извлечь, а также просмотр, "
+"публикацию и остановку сбора содержимого логов."
+
+msgid ""
+"Adds support for restricting the launch instance datastore field to the "
+"datastore and datastore version that the backup is relevant to.  It also "
+"populates the restored backup as the only option in the advanced step backup "
+"field."
+msgstr ""
+"Добавлена поддержка ограничения поля типа хранилища данных инстанса запуска "
+"типом хранилища данных и версией типа хранилища данных, к которым относится "
+"резервная копия. Также восстановленная резервная копия указывается как "
+"единственный вариант в поле расширенного резервного копирования."
+
+msgid ""
+"Admin users can stop database service inside an instance now. To get this "
+"feature work as expected operator should set the same values both in Horizon "
+"``OPENSTACK_KEYSTONE_ADMIN_ROLES`` and Trove ``admin_roles`` config files."
+msgstr ""
+"Администраторы теперь могут останавливать службу базы данных внутри "
+"инстанса. Чтобы эта функция работала как ожидается, пользователь должен "
+"установить одинаковые значения в файлах конфигурации Horizon "
+"``OPENSTACK_KEYSTONE_ADMIN_ROLES`` и Trove ``admin_roles``."
+
 msgid "Bug Fixes"
 msgstr "Исправления ошибок"
 
@@ -35,16 +110,146 @@ msgid "Contents:"
 msgstr "Содержание:"
 
 msgid "Current Series Release Notes"
-msgstr "Примечания к выпуску Current Series "
+msgstr "Примечания к текущему выпуску"
+
+msgid ""
+"Dashboard features now check the 'databases' policy file. If the "
+"corresponding API is not available to the current user, this UI element will "
+"not display or will appear disabled."
+msgstr ""
+"Функции панели управления теперь проверяют файл политики 'базы данных'. Если "
+"соответствующий API недоступен текущему пользователю, этот элемент "
+"интерфейса не будет отображаться или будет отображаться отключенным."
+
+msgid "Database category in menu, renamed in Databases."
+msgstr "Категория 'База данных' в меню, переименована в 'Базы данных'."
+
+msgid "Display all endpoints in the dashboard's cluster details endpoint list."
+msgstr ""
+"Отображение всех точек доступа в списке точек доступа в деталях кластера в "
+"панели управления."
+
+msgid ""
+"Django 2.0 is now supported and Django versions older than 1.11 are no "
+"longer supported aligning with Django versions supported by horizon. Note "
+"that Django 1.11 is still supported and this is the only version when you "
+"use python 2.7."
+msgstr ""
+"Django 2.0 теперь поддерживается, а версии Django старше 1.11 больше не "
+"поддерживаются, что соответствует версиям Django, поддерживаемым Horizon. "
+"Обратите внимание, что Django 1.11 все еще поддерживается, и это "
+"единственная версия, когда вы используете Python 2.7."
+
+msgid "Enable cluster grow and shrink panels for pxc."
+msgstr "Включены панели роста и уменьшения кластера для pxc."
 
 msgid "Enable cluster support for MariaDB and Cassandra."
-msgstr "Включить поддержку кластеризации в MariaDB и Cassandra."
+msgstr "Включена поддержка кластеров для MariaDB и Cassandra."
+
+msgid ""
+"Enables dashboard to select a configuration-id. We should select a "
+"configuration-id in cluster creation forms because we can select a "
+"configuration id when creating a database instance."
+msgstr ""
+"Позволяет панели управления выбирать id конфигурации. Необходимо выбрать id "
+"конфигурации в формах создания кластера, поскольку его можно выбрать при "
+"создании инстанса базы данных."
 
 msgid "New Features"
-msgstr "Новые особенности"
+msgstr "Новые возможности"
 
 msgid "Newton Series Release Notes"
-msgstr "Примечания к выпуску Newton Series "
+msgstr "Примечания к выпуску Newton"
+
+msgid "Ocata Series Release Notes"
+msgstr "Примечания к выпуску Ocata"
+
+msgid "Pike Series Release Notes"
+msgstr "Примечания к выпуску Pike"
+
+msgid ""
+"Python 2.7 support has been dropped. Last release of trove-dashboard to "
+"support py2.7 is OpenStack Train. The minimum version of Python now "
+"supported by trove-dashboard is Python 3.6."
+msgstr ""
+"Поддержка Python 2.7 была прекращена. Последний выпуск trove-dashboard, "
+"поддерживающий py2.7 — OpenStack Train. Минимальная версия Python, "
+"поддерживаемая trove-dashboard — Python 3.6."
+
+msgid ""
+"Python 3.6 & 3.7 support has been dropped. The minimum version of Python now "
+"supported is Python 3.8."
+msgstr ""
+"Поддержка Python 3.6 и 3.7 была прекращена. Минимальная версия Python, "
+"которая теперь поддерживается — Python 3.8."
+
+msgid ""
+"Python 3.8 support was dropped. The minimum version of Python now supported "
+"is Python 3.9."
+msgstr ""
+"Поддержка Python 3.8 была прекращена. Минимальная версия Python, которая "
+"теперь поддерживается — Python 3.9."
+
+msgid "Queens Series Release Notes"
+msgstr "Примечания к выпуску Queens"
+
+msgid "Rocky Series Release Notes"
+msgstr "Примечания к выпуску Rocky"
 
 msgid "Search"
 msgstr "Поиск"
+
+msgid "Stein Series Release Notes"
+msgstr "Примечания к выпуску Stein"
+
+msgid ""
+"Support configuration groups in the dashboard. This includes creating and "
+"deleting groups; adding, editing and removing parameters; attaching and "
+"detaching groups to running instances; and specifying a group during "
+"instance creation."
+msgstr ""
+"Поддержка групп конфигурации в панели управления. Это включает в себя "
+"создание и удаление групп; добавление, редактирование и удаление параметров; "
+"присоединение и отсоединение групп к запущенным инстансам; и указание группы "
+"во время создания инстанса."
+
+msgid ""
+"The current caching initializes the instance list for the grow cluster "
+"manager each time a new process would instantiate the manager.  Changed to "
+"manager to only initialize on creation."
+msgstr ""
+"Текущее кэширование инициализирует список инстансов для менеджера увеличения "
+"кластера каждый раз, когда новый процесс инициирует менеджер.  Изменено на "
+"то, чтобы менеджер инициировлся только при создании."
+
+msgid "Train Series Release Notes"
+msgstr "Примечания к выпуску Train"
+
+msgid "Trove Dashboard Release Notes"
+msgstr "Примечания к выпуску панели управления Trove"
+
+msgid "Upgrade Notes"
+msgstr "Примечания к обновлению"
+
+msgid "Users can rename database instances via dashboard."
+msgstr ""
+"Пользователи могут переименовать инстансы базы данных через панель "
+"управления."
+
+msgid "Ussuri Series Release Notes"
+msgstr "Примечания к выпуску Ussuri"
+
+msgid "Victoria Series Release Notes"
+msgstr "Примечания к выпуску Victoria"
+
+msgid "Wallaby Series Release Notes"
+msgstr "Примечания к выпуску Wallaby"
+
+msgid "Xena Series Release Notes"
+msgstr "Примечания к выпуску Xena"
+
+msgid "Yoga Series Release Notes"
+msgstr "Примечания к выпуску Yoga"
+
+msgid "Zed Series Release Notes"
+msgstr "Примечания к выпуску Zed"
diff -pruN 24.0.0-1/releasenotes/source/zed.rst 25.0.0~rc1-1/releasenotes/source/zed.rst
--- 24.0.0-1/releasenotes/source/zed.rst	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/releasenotes/source/zed.rst	2025-09-09 03:44:01.000000000 +0000
@@ -3,4 +3,4 @@ Zed Series Release Notes
 ========================
 
 .. release-notes::
-   :branch: stable/zed
+   :branch: unmaintained/zed
diff -pruN 24.0.0-1/setup.cfg 25.0.0~rc1-1/setup.cfg
--- 24.0.0-1/setup.cfg	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/setup.cfg	2025-09-09 03:44:01.000000000 +0000
@@ -3,24 +3,24 @@ name = trove-dashboard
 summary = Trove Management Dashboard
 description_file =
     README.rst
+license = Apache-2.0
 author = OpenStack
 author_email = openstack-discuss@lists.openstack.org
 home_page = https://docs.openstack.org/trove/latest
-python_requires = >=3.8
+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 :: Implementation :: CPython
     Programming Language :: Python :: 3 :: Only
     Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.8
     Programming Language :: Python :: 3.9
     Programming Language :: Python :: 3.10
     Programming Language :: Python :: 3.11
+    Programming Language :: Python :: 3.12
 
 [files]
 packages =
diff -pruN 24.0.0-1/tox.ini 25.0.0~rc1-1/tox.ini
--- 24.0.0-1/tox.ini	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/tox.ini	2025-09-09 03:44:01.000000000 +0000
@@ -1,8 +1,6 @@
 [tox]
-minversion = 3.1.1
-envlist = py39,pep8
-skipsdist = True
-ignore_basepython_conflict = True
+minversion = 3.18.0
+envlist = pep8,py3
 
 [testenv]
 usedevelop = True
diff -pruN 24.0.0-1/trove_dashboard/api/trove.py 25.0.0~rc1-1/trove_dashboard/api/trove.py
--- 24.0.0-1/trove_dashboard/api/trove.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/api/trove.py	2025-09-09 03:44:01.000000000 +0000
@@ -69,7 +69,8 @@ def cluster_delete(request, cluster_id):
 
 def cluster_create(request, name, volume, flavor, num_instances,
                    datastore, datastore_version,
-                   nics=None, root_password=None, locality=None):
+                   nics=None, root_password=None, locality=None,
+                   configuration=None):
     instances = []
     for i in range(num_instances):
         instance = {}
@@ -86,7 +87,8 @@ def cluster_create(request, name, volume
         datastore,
         datastore_version,
         instances=instances,
-        locality=locality)
+        locality=locality,
+        configuration=configuration)
 
 
 def cluster_grow(request, cluster_id, new_instances):
@@ -414,10 +416,9 @@ def log_discard(request, instance_id, lo
                                                      discard=True)
 
 
-def log_tail(request, instance_id, log_name, publish, lines, swift=None):
+def log_tail(request, instance_id, log_name, lines, swift=None):
     return troveclient(request).instances.log_generator(instance_id,
                                                         log_name,
-                                                        publish=publish,
                                                         lines=lines,
                                                         swift=swift)
 
diff -pruN 24.0.0-1/trove_dashboard/content/backup_strategies/tables.py 25.0.0~rc1-1/trove_dashboard/content/backup_strategies/tables.py
--- 24.0.0-1/trove_dashboard/content/backup_strategies/tables.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/backup_strategies/tables.py	2025-09-09 03:44:01.000000000 +0000
@@ -26,22 +26,25 @@ class CreateBackupStrategy(tables.LinkAc
     url = "horizon:project:backup_strategies:create"
     classes = ("ajax-modal", "btn-create")
     icon = "camera"
+    policy_rules = (("database", "backup_strategy:create"), )
 
 
 class DeleteBackupStrategy(tables.DeleteAction):
+    policy_rules = (("database", "backup_strategy:delete"), )
+
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Backup Strategy",
-            u"Delete Backup Strategies",
+            "Delete Backup Strategy",
+            "Delete Backup Strategies",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Backup Strategy Deleted",
-            u"Backup Strategies Deleted",
+            "Backup Strategy Deleted",
+            "Backup Strategies Deleted",
             count
         )
 
@@ -52,7 +55,7 @@ class DeleteBackupStrategy(tables.Delete
 class BackupStrategiesTable(tables.DataTable):
     backend = tables.Column("backend", verbose_name=_("Backend"))
     instance_id = tables.Column("instance_id",
-                                verbose_name=_("instance_id"))
+                                verbose_name=_("Instance ID"))
     project_id = tables.Column("project_id",
                                verbose_name=_("Project"))
     swift_container = tables.Column("swift_container",
diff -pruN 24.0.0-1/trove_dashboard/content/database_backups/tables.py 25.0.0~rc1-1/trove_dashboard/content/database_backups/tables.py
--- 24.0.0-1/trove_dashboard/content/database_backups/tables.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_backups/tables.py	2025-09-09 03:44:01.000000000 +0000
@@ -36,19 +36,19 @@ STATUS_CHOICES = (
 )
 STATUS_DISPLAY_CHOICES = (
     ("BUILDING", pgettext_lazy("Current status of a Database Backup",
-                               u"Building")),
+                               "Building")),
     ("COMPLETED", pgettext_lazy("Current status of a Database Backup",
-                                u"Completed")),
+                                "Completed")),
     ("DELETE_FAILED", pgettext_lazy("Current status of a Database Backup",
-                                    u"Delete Failed")),
+                                    "Delete Failed")),
     ("FAILED", pgettext_lazy("Current status of a Database Backup",
-                             u"Failed")),
+                             "Failed")),
     ("NEW", pgettext_lazy("Current status of a Database Backup",
-                          u"New")),
+                          "New")),
     ("RESTORED", pgettext_lazy("Current status of a Database Backup",
-                               u"Restored")),
+                               "Restored")),
     ("SAVING", pgettext_lazy("Current status of a Database Backup",
-                             u"Saving")),
+                             "Saving")),
 )
 
 
@@ -58,6 +58,7 @@ class LaunchLink(tables.LinkAction):
     url = "horizon:project:database_backups:create"
     classes = ("ajax-modal", "btn-create")
     icon = "camera"
+    policy_rules = (("database", "backup:create"), )
 
 
 class RestoreLink(tables.LinkAction):
@@ -66,6 +67,7 @@ class RestoreLink(tables.LinkAction):
     url = "horizon:project:databases:launch"
     classes = ("ajax-modal",)
     icon = "cloud-upload"
+    policy_rules = (("database", "backup:show"), )
 
     def allowed(self, request, backup=None):
         return backup.status in ['COMPLETED', 'RESTORED']
@@ -80,6 +82,7 @@ class DownloadBackup(tables.LinkAction):
     verbose_name = _("Download Backup")
     url = 'horizon:project:containers:object_download'
     classes = ("btn-download",)
+    policy_rules = (("database", "backup:show"), )
 
     def get_link_url(self, datum):
         ref = datum.locationRef.split('/')
@@ -99,19 +102,21 @@ class DownloadBackup(tables.LinkAction):
 
 
 class DeleteBackup(tables.DeleteAction):
+    policy_rules = (("database", "backup:delete"), )
+
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Backup",
-            u"Delete Backups",
+            "Delete Backup",
+            "Delete Backups",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Deleted Backup",
-            u"Deleted Backups",
+            "Deleted Backup",
+            "Deleted Backups",
             count
         )
 
diff -pruN 24.0.0-1/trove_dashboard/content/database_clusters/forms.py 25.0.0~rc1-1/trove_dashboard/content/database_clusters/forms.py
--- 24.0.0-1/trove_dashboard/content/database_clusters/forms.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_clusters/forms.py	2025-09-09 03:44:01.000000000 +0000
@@ -40,7 +40,51 @@ from trove_dashboard.utils import common
 LOG = logging.getLogger(__name__)
 
 
-class LaunchForm(forms.SelfHandlingForm):
+class BaseClusterForm(forms.SelfHandlingForm):
+    def __init__(self, request, *args, **kwargs):
+        super(BaseClusterForm, self).__init__(request, *args, **kwargs)
+
+    @memoized.memoized_method
+    def populate_network_choices(self, request):
+        network_list = []
+        try:
+            if api.base.is_service_enabled(request, 'network'):
+                tenant_id = self.request.user.tenant_id
+                networks = api.neutron.network_list_for_tenant(request,
+                                                               tenant_id)
+                network_list = [(network.id, network.name_or_id)
+                                for network in networks]
+            else:
+                self.fields['network'].widget = forms.HiddenInput()
+        except exceptions.ServiceCatalogException:
+            network_list = []
+            redirect = reverse('horizon:project:database_clusters:index')
+            exceptions.handle(request,
+                              _('Unable to retrieve networks.'),
+                              redirect=redirect)
+        return network_list
+
+    @memoized.memoized_method
+    def populate_cg_choices(self, request):
+        try:
+            configs = trove_api.trove.configuration_list(request)
+            config_name = "%(name)s (%(datastore)s - %(version)s)"
+            choices = [(c.id,
+                        config_name % {'name': c.name,
+                                       'datastore': c.datastore_name,
+                                       'version': c.datastore_version_name})
+                       for c in configs]
+        except Exception:
+            choices = []
+
+        if choices:
+            choices.insert(0, ("", _("Select configuration")))
+        else:
+            choices.insert(0, ("", _("No configurations available")))
+        return choices
+
+
+class LaunchForm(BaseClusterForm):
     name = forms.CharField(label=_("Cluster Name"),
                            max_length=80)
     datastore = forms.ChoiceField(
@@ -60,7 +104,7 @@ class LaunchForm(forms.SelfHandlingForm)
         initial=1,
         help_text=_("Size of the volume in GB."))
     locality = forms.ChoiceField(
-        label=_("Locality"),
+        label=_("Location Policy"),
         choices=[("", "None"),
                  ("affinity", "affinity"),
                  ("anti-affinity", "anti-affinity")],
@@ -68,6 +112,10 @@ class LaunchForm(forms.SelfHandlingForm)
         help_text=_("Specify whether instances in the cluster will "
                     "be created on the same hypervisor (affinity) or on "
                     "different hypervisors (anti-affinity)."))
+    configuration = forms.ChoiceField(
+        label=_("Configuration Group"),
+        help_text=_("Configuration Group attached to instances."),
+        required=False)
     root_password = forms.CharField(
         label=_("Root Password"),
         required=False,
@@ -81,7 +129,7 @@ class LaunchForm(forms.SelfHandlingForm)
         min_value=3,
         initial=3,
         required=False,
-        help_text=_("Number of instances in the cluster. (Read only)"),
+        help_text=_("Number of instances in the cluster (read only)."),
         widget=forms.TextInput(attrs={
             'readonly': 'readonly',
             'class': 'switched',
@@ -92,7 +140,7 @@ class LaunchForm(forms.SelfHandlingForm)
         min_value=1,
         initial=1,
         required=False,
-        help_text=_("Number of shards. (Read only)"),
+        help_text=_("Number of shards (read only)."),
         widget=forms.TextInput(attrs={
             'readonly': 'readonly',
             'class': 'switched',
@@ -127,6 +175,8 @@ class LaunchForm(forms.SelfHandlingForm)
             request)
         self.fields['network'].choices = self.populate_network_choices(
             request)
+        self.fields['configuration'].choices = self.populate_cg_choices(
+            request)
 
     def clean(self):
         datastore_field_value = self.data.get("datastore", None)
@@ -158,6 +208,9 @@ class LaunchForm(forms.SelfHandlingForm)
         if not self.data.get("locality", None):
             self.cleaned_data["locality"] = None
 
+        if not self.data.get("configuration", None):
+            self.cleaned_data["configuration"] = None
+
         return self.cleaned_data
 
     @memoized.memoized_method
@@ -174,26 +227,6 @@ class LaunchForm(forms.SelfHandlingForm)
                               redirect=redirect)
 
     @memoized.memoized_method
-    def populate_network_choices(self, request):
-        network_list = []
-        try:
-            if api.base.is_service_enabled(request, 'network'):
-                tenant_id = self.request.user.tenant_id
-                networks = api.neutron.network_list_for_tenant(request,
-                                                               tenant_id)
-                network_list = [(network.id, network.name_or_id)
-                                for network in networks]
-            else:
-                self.fields['network'].widget = forms.HiddenInput()
-        except exceptions.ServiceCatalogException:
-            network_list = []
-            redirect = reverse('horizon:project:database_clusters:index')
-            exceptions.handle(request,
-                              _('Unable to retrieve networks.'),
-                              redirect=redirect)
-        return network_list
-
-    @memoized.memoized_method
     def datastores(self, request):
         try:
             return trove_api.trove.datastore_list(request)
@@ -354,9 +387,10 @@ class LaunchForm(forms.SelfHandlingForm)
             LOG.info("Launching cluster with parameters "
                      "{name=%s, volume=%s, flavor=%s, "
                      "datastore=%s, datastore_version=%s",
-                     "locality=%s",
+                     "locality=%s, configuration=%s",
                      data['name'], data['volume'], flavor,
-                     datastore, datastore_version, self._get_locality(data))
+                     datastore, datastore_version, self._get_locality(data),
+                     configuration=data['configuration'])
 
             trove_api.trove.cluster_create(request,
                                            data['name'],
@@ -367,7 +401,8 @@ class LaunchForm(forms.SelfHandlingForm)
                                            datastore_version=datastore_version,
                                            nics=data['network'],
                                            root_password=root_password,
-                                           locality=self._get_locality(data))
+                                           locality=self._get_locality(data),
+                                           configuration=data['configuration'])
             messages.success(request,
                              _('Launched cluster "%s"') % data['name'])
             return True
@@ -378,7 +413,7 @@ class LaunchForm(forms.SelfHandlingForm)
                               redirect=redirect)
 
 
-class ClusterAddInstanceForm(forms.SelfHandlingForm):
+class ClusterAddInstanceForm(BaseClusterForm):
     cluster_id = forms.CharField(
         required=False,
         widget=forms.HiddenInput())
@@ -408,6 +443,10 @@ class ClusterAddInstanceForm(forms.SelfH
         label=_("Network"),
         help_text=_("Network attached to instance."),
         required=False)
+    configuration = forms.ChoiceField(
+        label=_("Configuration Group"),
+        help_text=_("Configuration Group attached to instance."),
+        required=False)
 
     def __init__(self, request, *args, **kwargs):
         super(ClusterAddInstanceForm, self).__init__(request, *args, **kwargs)
@@ -415,6 +454,8 @@ class ClusterAddInstanceForm(forms.SelfH
         self.fields['flavor'].choices = self.populate_flavor_choices(request)
         self.fields['network'].choices = self.populate_network_choices(
             request)
+        self.fields['configuration'].choices = self.populate_cg_choices(
+            request)
 
     @memoized.memoized_method
     def flavors(self, request):
@@ -441,26 +482,6 @@ class ClusterAddInstanceForm(forms.SelfH
         flavor_list = [(f.id, "%s" % f.name) for f in self.flavors(request)]
         return sorted(flavor_list)
 
-    @memoized.memoized_method
-    def populate_network_choices(self, request):
-        network_list = []
-        try:
-            if api.base.is_service_enabled(request, 'network'):
-                tenant_id = self.request.user.tenant_id
-                networks = api.neutron.network_list_for_tenant(request,
-                                                               tenant_id)
-                network_list = [(network.id, network.name_or_id)
-                                for network in networks]
-            else:
-                self.fields['network'].widget = forms.HiddenInput()
-        except exceptions.ServiceCatalogException:
-            network_list = []
-            redirect = reverse('horizon:project:database_clusters:index')
-            exceptions.handle(request,
-                              _('Unable to retrieve networks.'),
-                              redirect=redirect)
-        return network_list
-
     def handle(self, request, data):
         try:
             flavor = trove_api.trove.flavor_get(request, data['flavor'])
diff -pruN 24.0.0-1/trove_dashboard/content/database_clusters/panel.py 25.0.0~rc1-1/trove_dashboard/content/database_clusters/panel.py
--- 24.0.0-1/trove_dashboard/content/database_clusters/panel.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_clusters/panel.py	2025-09-09 03:44:01.000000000 +0000
@@ -17,6 +17,7 @@
 from django.utils.translation import gettext_lazy as _
 
 import horizon
+from openstack_dashboard.dashboards.project import dashboard
 
 
 class Clusters(horizon.Panel):
@@ -25,4 +26,4 @@ class Clusters(horizon.Panel):
     permissions = ('openstack.services.database',)
 
 
-# dashboard.Project.register(Clusters)
+dashboard.Project.register(Clusters)
diff -pruN 24.0.0-1/trove_dashboard/content/database_clusters/tables.py 25.0.0~rc1-1/trove_dashboard/content/database_clusters/tables.py
--- 24.0.0-1/trove_dashboard/content/database_clusters/tables.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_clusters/tables.py	2025-09-09 03:44:01.000000000 +0000
@@ -42,20 +42,21 @@ class DeleteCluster(tables.BatchAction):
     icon = "remove"
     classes = ('btn-danger',)
     help_text = _("Deleted cluster is not recoverable.")
+    policy_rules = (("database", "cluster:delete"), )
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Cluster",
-            u"Delete Clusters",
+            "Delete Cluster",
+            "Delete Clusters",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Scheduled deletion of Cluster",
-            u"Scheduled deletion of Clusters",
+            "Scheduled deletion of Cluster",
+            "Scheduled deletion of Clusters",
             count
         )
 
@@ -69,12 +70,14 @@ class LaunchLink(tables.LinkAction):
     url = "horizon:project:database_clusters:launch"
     classes = ("btn-launch", "ajax-modal")
     icon = "cloud-upload"
+    policy_rules = (("database", "cluster:create"), )
 
 
 class ClusterGrow(tables.LinkAction):
     name = "cluster_grow"
     verbose_name = _("Grow Cluster")
     url = "horizon:project:database_clusters:cluster_grow_details"
+    policy_rules = (("database", "cluster:action"), )
 
     def allowed(self, request, cluster=None):
         if (cluster and cluster.task["name"] == 'NONE' and
@@ -87,6 +90,7 @@ class ClusterShrink(tables.LinkAction):
     name = "cluster_shrink"
     verbose_name = _("Shrink Cluster")
     url = "horizon:project:database_clusters:cluster_shrink_details"
+    policy_rules = (("database", "cluster:action"), )
 
     def allowed(self, request, cluster=None):
         if (cluster and cluster.task["name"] == 'NONE' and
@@ -100,6 +104,7 @@ class ResetPassword(tables.LinkAction):
     verbose_name = _("Reset Root Password")
     url = "horizon:project:database_clusters:reset_password"
     classes = ("ajax-modal",)
+    policy_rules = (("database", "cluster:action"), )
 
     def allowed(self, request, cluster=None):
         if (cluster and cluster.task["name"] == 'NONE' and
@@ -241,20 +246,21 @@ class ClusterShrinkAction(tables.BatchAc
     classes = ('btn-danger',)
     success_url = 'horizon:project:database_clusters:index'
     help_text = _("Shrinking a cluster is not recoverable.")
+    policy_rules = (("database", "cluster:delete"), )
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Shrink Cluster",
-            u"Shrink Cluster",
+            "Shrink Cluster",
+            "Shrink Cluster",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Scheduled Shrinking of Cluster",
-            u"Scheduled Shrinking of Cluster",
+            "Scheduled Shrinking of Cluster",
+            "Scheduled Shrinking of Cluster",
             count
         )
 
@@ -305,6 +311,7 @@ class ClusterGrowAddInstance(tables.Link
     verbose_name = _("Add Instance")
     url = "horizon:project:database_clusters:add_instance"
     classes = ("ajax-modal",)
+    policy_rules = (("database", "cluster:action"), )
 
     def get_link_url(self):
         return urls.reverse(
@@ -313,20 +320,21 @@ class ClusterGrowAddInstance(tables.Link
 
 class ClusterGrowRemoveInstance(tables.BatchAction):
     name = "cluster_grow_remove_instance"
+    policy_rules = (("database", "cluster:action"), )
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Remove Instance",
-            u"Remove Instances",
+            "Remove Instance",
+            "Remove Instances",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Removed Instance",
-            u"Removed Instances",
+            "Removed Instance",
+            "Removed Instances",
             count
         )
 
@@ -387,6 +395,7 @@ class ClusterGrowAction(tables.Action):
     verbose_name_plural = _("Grow Cluster")
     requires_input = False
     icon = "plus"
+    policy_rules = (("database", "cluster:action"), )
 
     def handle(self, table, request, obj_ids):
         if not table.data:
diff -pruN 24.0.0-1/trove_dashboard/content/database_clusters/templates/database_clusters/_detail_overview.html 25.0.0~rc1-1/trove_dashboard/content/database_clusters/templates/database_clusters/_detail_overview.html
--- 24.0.0-1/trove_dashboard/content/database_clusters/templates/database_clusters/_detail_overview.html	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_clusters/templates/database_clusters/_detail_overview.html	2025-09-09 03:44:01.000000000 +0000
@@ -17,7 +17,7 @@
         <dt>{% trans "Number of Instances" %}</dt>
         <dd>{{ cluster.num_instances }}</dd>
         {% if cluster.locality %}
-            <dt>{% trans "Locality" %}</dt>
+            <dt>{% trans "Location Policy" %}</dt>
             <dd>{{ cluster.locality }}</dd>
         {% endif %}
     </dl>
diff -pruN 24.0.0-1/trove_dashboard/content/database_clusters/tests.py 25.0.0~rc1-1/trove_dashboard/content/database_clusters/tests.py
--- 24.0.0-1/trove_dashboard/content/database_clusters/tests.py	1970-01-01 00:00:00.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_clusters/tests.py	2025-09-09 03:44:01.000000000 +0000
@@ -0,0 +1,682 @@
+# Copyright (c) 2014 eBay Software Foundation
+# Copyright 2015 HP Software, LLC
+# All Rights Reserved.
+#
+#    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 logging
+from unittest import mock
+
+from django.urls import reverse
+from openstack_dashboard import api
+from troveclient import common
+
+from trove_dashboard import api as trove_api
+from trove_dashboard.content.database_clusters \
+    import cluster_manager
+from trove_dashboard.content.database_clusters import tables
+from trove_dashboard.test import helpers as test
+from trove_dashboard.utils import common as common_utils
+
+INDEX_URL = reverse('horizon:project:database_clusters:index')
+LAUNCH_URL = reverse('horizon:project:database_clusters:launch')
+DETAILS_URL = reverse('horizon:project:database_clusters:detail', args=['id'])
+RESET_PASSWORD_VIEWNAME = 'horizon:project:database_clusters:reset_password'
+
+
+class ClustersTests(test.TestCase):
+    @test.create_mocks({trove_api.trove: ('cluster_list',
+                                          'flavor_list')})
+    def test_index(self):
+        clusters = common.Paginated(self.trove_clusters.list())
+        self.mock_cluster_list.return_value = clusters
+        self.mock_flavor_list.return_value = self.flavors.list()
+
+        res = self.client.get(INDEX_URL)
+        self.mock_cluster_list.assert_called_once_with(
+            test.IsHttpRequest(), marker=None)
+        self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
+        self.assertTemplateUsed(res, 'project/database_clusters/index.html')
+
+    @test.create_mocks({trove_api.trove: ('cluster_list',
+                                          'flavor_list')})
+    def test_index_flavor_exception(self):
+        clusters = common.Paginated(self.trove_clusters.list())
+        self.mock_cluster_list.return_value = clusters
+        self.mock_flavor_list.side_effect = self.exceptions.trove
+
+        res = self.client.get(INDEX_URL)
+        self.mock_cluster_list.assert_called_once_with(
+            test.IsHttpRequest(), marker=None)
+        self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
+        self.assertTemplateUsed(res, 'project/database_clusters/index.html')
+        self.assertMessageCount(res, error=1)
+
+    @test.create_mocks({trove_api.trove: ('cluster_list',)})
+    def test_index_list_exception(self):
+        self.mock_cluster_list.side_effect = self.exceptions.trove
+
+        res = self.client.get(INDEX_URL)
+        self.mock_cluster_list.assert_called_once_with(
+            test.IsHttpRequest(), marker=None)
+        self.assertTemplateUsed(res, 'project/database_clusters/index.html')
+        self.assertMessageCount(res, error=1)
+
+    @test.create_mocks({trove_api.trove: ('cluster_list',
+                                          'flavor_list')})
+    def test_index_pagination(self):
+        clusters = self.trove_clusters.list()
+        last_record = clusters[1]
+        clusters = common.Paginated(clusters, next_marker="foo")
+        self.mock_cluster_list.return_value = clusters
+        self.mock_flavor_list.return_value = self.flavors.list()
+
+        res = self.client.get(INDEX_URL)
+        self.mock_cluster_list.assert_called_once_with(
+            test.IsHttpRequest(), marker=None)
+        self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
+        self.assertTemplateUsed(res, 'project/database_clusters/index.html')
+        self.assertContains(
+            res, 'marker=' + last_record.id)
+
+    @test.create_mocks({trove_api.trove: ('datastore_flavors',
+                                          'datastore_list',
+                                          'datastore_version_list'),
+                        api.base: ['is_service_enabled']})
+    def test_launch_cluster(self):
+        self.mock_is_service_enabled.return_value = False
+        self.mock_datastore_flavors.return_value = self.flavors.list()
+
+        filtered_datastores = self._get_filtered_datastores('mongodb')
+        self.mock_datastore_list.return_value = filtered_datastores
+        self.mock_datastore_version_list.return_value = (
+            self._get_filtered_datastore_versions(filtered_datastores))
+
+        res = self.client.get(LAUNCH_URL)
+        self.mock_is_service_enabled.assert_called_once_with(
+            test.IsHttpRequest(), 'network')
+        self.mock_datastore_flavors.assert_called_once_with(
+            test.IsHttpRequest(), 'mongodb', '2.6')
+        self.mock_datastore_list.assert_called_once_with(test.IsHttpRequest())
+        self.mock_datastore_version_list.assert_called_once_with(
+            test.IsHttpRequest(), test.IsA(str))
+        self.assertTemplateUsed(res, 'project/database_clusters/launch.html')
+
+    def test_launch_cluster_mongo_fields(self):
+        datastore = 'mongodb'
+        datastore_version = '2.6'
+        fields = self.launch_cluster_fields_setup(datastore,
+                                                  datastore_version)
+        field_name = self._build_flavor_widget_name(datastore,
+                                                    datastore_version)
+
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields[field_name], field_name))
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields['num_instances'], field_name))
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields['num_shards'], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['root_password'], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['num_instances_vertica'], field_name))
+
+    def test_launch_cluster_redis_fields(self):
+        datastore = 'redis'
+        datastore_version = '3.0'
+        fields = self.launch_cluster_fields_setup(datastore,
+                                                  datastore_version)
+        field_name = self._build_flavor_widget_name(datastore,
+                                                    datastore_version)
+
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields[field_name], field_name))
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields['num_instances'], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['num_shards'], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['root_password'], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['num_instances_vertica'], field_name))
+
+    def test_launch_cluster_vertica_fields(self):
+        datastore = 'vertica'
+        datastore_version = '7.1'
+        fields = self.launch_cluster_fields_setup(datastore,
+                                                  datastore_version)
+        field_name = self._build_flavor_widget_name(datastore,
+                                                    datastore_version)
+
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields[field_name], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['num_instances'], field_name))
+        self.assertFalse(self._contains_datastore_in_attribute(
+            fields['num_shards'], field_name))
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields['root_password'], field_name))
+        self.assertTrue(self._contains_datastore_in_attribute(
+            fields['num_instances_vertica'], field_name))
+
+    @test.create_mocks({trove_api.trove: ('datastore_flavors',
+                                          'datastore_list',
+                                          'datastore_version_list'),
+                        api.base: ['is_service_enabled']})
+    def launch_cluster_fields_setup(self, datastore, datastore_version):
+        self.mock_is_service_enabled.return_value = False
+        self.mock_datastore_flavors.return_value = self.flavors.list()
+
+        filtered_datastores = self._get_filtered_datastores(datastore)
+        self.mock_datastore_list.return_value = filtered_datastores
+        self.mock_datastore_version_list.return_value = (
+            self._get_filtered_datastore_versions(filtered_datastores))
+
+        res = self.client.get(LAUNCH_URL)
+        self.mock_is_service_enabled.assert_called_once_with(
+            test.IsHttpRequest(), 'network')
+        self.mock_datastore_flavors.assert_called_once_with(
+            test.IsHttpRequest(), datastore, datastore_version)
+        self.mock_datastore_list.assert_called_once_with(test.IsHttpRequest())
+        self.mock_datastore_version_list.assert_called_once_with(
+            test.IsHttpRequest(), test.IsA(str))
+        return res.context_data['form'].fields
+
+    @test.create_mocks({trove_api.trove: ['datastore_flavors',
+                                          'cluster_create',
+                                          'datastore_list',
+                                          'datastore_version_list'],
+                        api.base: ['is_service_enabled']})
+    def test_create_simple_cluster(self):
+        self.mock_is_service_enabled.return_value = False
+        self.mock_datastore_flavors.return_value = self.flavors.list()
+
+        filtered_datastores = self._get_filtered_datastores('mongodb')
+        self.mock_datastore_list.return_value = filtered_datastores
+        self.mock_datastore_version_list.return_value = (
+            self._get_filtered_datastore_versions(filtered_datastores))
+
+        self.mock_cluster_create.return_value = self.trove_clusters.first()
+
+        cluster_name = 'MyCluster'
+        cluster_volume = 1
+        cluster_flavor = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
+        cluster_instances = 3
+        cluster_datastore = 'mongodb'
+        cluster_datastore_version = '2.6'
+        cluster_network = ''
+
+        field_name = self._build_flavor_widget_name(cluster_datastore,
+                                                    cluster_datastore_version)
+        post = {
+            'name': cluster_name,
+            'volume': cluster_volume,
+            'num_instances': cluster_instances,
+            'num_shards': 1,
+            'datastore': field_name,
+            field_name: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
+        }
+
+        res = self.client.post(LAUNCH_URL, post)
+        self.mock_is_service_enabled.assert_called_once_with(
+            test.IsHttpRequest(), 'network')
+        self.mock_datastore_flavors.assert_called_once_with(
+            test.IsHttpRequest(), 'mongodb', '2.6')
+        self.mock_datastore_list.assert_called_once_with(test.IsHttpRequest())
+        self.mock_datastore_version_list.assert_called_once_with(
+            test.IsHttpRequest(), test.IsA(str))
+        self.mock_cluster_create.assert_called_once_with(
+            test.IsHttpRequest(),
+            cluster_name,
+            cluster_volume,
+            cluster_flavor,
+            cluster_instances,
+            datastore=cluster_datastore,
+            datastore_version=cluster_datastore_version,
+            nics=cluster_network,
+            root_password=None,
+            locality=None,
+            configuration=None)
+        self.assertNoFormErrors(res)
+        self.assertMessageCount(success=1)
+
+    @test.create_mocks({trove_api.trove: ['datastore_flavors',
+                                          'cluster_create',
+                                          'datastore_list',
+                                          'datastore_version_list'],
+                        api.neutron: ['network_list_for_tenant'],
+                        api.base: ['is_service_enabled']})
+    def test_create_simple_cluster_neutron(self):
+        self.mock_is_service_enabled.return_value = True
+        self.mock_network_list_for_tenant.return_value = self.networks.list()
+        self.mock_datastore_flavors.return_value = self.flavors.list()
+
+        filtered_datastores = self._get_filtered_datastores('mongodb')
+        self.mock_datastore_list.return_value = filtered_datastores
+        self.mock_datastore_version_list.return_value = (
+            self._get_filtered_datastore_versions(filtered_datastores))
+
+        self.mock_cluster_create.return_value = self.trove_clusters.first()
+
+        cluster_name = 'MyCluster'
+        cluster_volume = 1
+        cluster_flavor = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
+        cluster_instances = 3
+        cluster_datastore = 'mongodb'
+        cluster_datastore_version = '2.6'
+        cluster_network = '82288d84-e0a5-42ac-95be-e6af08727e42'
+
+        field_name = self._build_flavor_widget_name(cluster_datastore,
+                                                    cluster_datastore_version)
+        post = {
+            'name': cluster_name,
+            'volume': cluster_volume,
+            'num_instances': cluster_instances,
+            'num_shards': 1,
+            'datastore': field_name,
+            field_name: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
+            'network': cluster_network,
+        }
+
+        res = self.client.post(LAUNCH_URL, post)
+        self.mock_is_service_enabled.assert_called_once_with(
+            test.IsHttpRequest(), 'network')
+        self.mock_network_list_for_tenant.assert_called_once_with(
+            test.IsHttpRequest(), '1')
+        self.mock_datastore_flavors.assert_called_once_with(
+            test.IsHttpRequest(), 'mongodb', '2.6')
+        self.mock_datastore_list.assert_called_once_with(test.IsHttpRequest())
+        self.mock_datastore_version_list.assert_called_once_with(
+            test.IsHttpRequest(), test.IsA(str))
+        self.mock_cluster_create.assert_called_once_with(
+            test.IsHttpRequest(),
+            cluster_name,
+            cluster_volume,
+            cluster_flavor,
+            cluster_instances,
+            datastore=cluster_datastore,
+            datastore_version=cluster_datastore_version,
+            nics=cluster_network,
+            root_password=None,
+            locality=None,
+            configuration=None)
+        self.assertNoFormErrors(res)
+        self.assertMessageCount(success=1)
+
+    @test.create_mocks({trove_api.trove: ['datastore_flavors',
+                                          'cluster_create',
+                                          'datastore_list',
+                                          'datastore_version_list'],
+                        api.neutron: ['network_list_for_tenant']})
+    def test_create_simple_cluster_exception(self):
+        self.mock_network_list_for_tenant.return_value = self.networks.list()
+        self.mock_datastore_flavors.return_value = self.flavors.list()
+
+        filtered_datastores = self._get_filtered_datastores('mongodb')
+        self.mock_datastore_list.return_value = filtered_datastores
+        self.mock_datastore_version_list.return_value = (
+            self._get_filtered_datastore_versions(filtered_datastores))
+
+        self.mock_cluster_create.side_effect = self.exceptions.trove
+
+        cluster_name = 'MyCluster'
+        cluster_volume = 1
+        cluster_flavor = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
+        cluster_instances = 3
+        cluster_datastore = 'mongodb'
+        cluster_datastore_version = '2.6'
+        cluster_network = ''
+
+        field_name = self._build_flavor_widget_name(cluster_datastore,
+                                                    cluster_datastore_version)
+        post = {
+            'name': cluster_name,
+            'volume': cluster_volume,
+            'num_instances': cluster_instances,
+            'num_shards': 1,
+            'datastore': field_name,
+            field_name: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
+        }
+
+        res = self.client.post(LAUNCH_URL, post)
+        self.mock_network_list_for_tenant.assert_called_once_with(
+            test.IsHttpRequest(), '1')
+        self.mock_datastore_flavors.assert_called_once_with(
+            test.IsHttpRequest(), 'mongodb', '2.6')
+        self.mock_datastore_list.assert_called_once_with(test.IsHttpRequest())
+        self.mock_datastore_version_list.assert_called_once_with(
+            test.IsHttpRequest(), test.IsA(str))
+        self.mock_cluster_create.assert_called_once_with(
+            test.IsHttpRequest(),
+            cluster_name,
+            cluster_volume,
+            cluster_flavor,
+            cluster_instances,
+            datastore=cluster_datastore,
+            datastore_version=cluster_datastore_version,
+            nics=cluster_network,
+            root_password=None,
+            locality=None,
+            configuration=None)
+        self.assertRedirectsNoFollow(res, INDEX_URL)
+        self.assertMessageCount(error=1)
+
+    @test.create_mocks({trove_api.trove: ('cluster_get',
+                                          'instance_get',
+                                          'flavor_get',)})
+    def test_details(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+        self.mock_instance_get.return_value = self.databases.first()
+        self.mock_flavor_get.return_value = self.flavors.first()
+
+        details_url = reverse('horizon:project:database_clusters:detail',
+                              args=[cluster.id])
+        res = self.client.get(details_url)
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_cluster_get, 2,
+            mock.call(test.IsHttpRequest(), cluster.id))
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_instance_get, 3,
+            mock.call(test.IsHttpRequest(), test.IsA(str)))
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_flavor_get, 4,
+            mock.call(test.IsHttpRequest(), test.IsA(str)))
+        self.assertTemplateUsed(res, 'horizon/common/_detail.html')
+        self.assertContains(res, cluster.ip[0])
+
+    @test.create_mocks({trove_api.trove: ('cluster_get',
+                                          'instance_get',
+                                          'flavor_get',)})
+    def test_details_without_locality(self):
+        cluster = self.trove_clusters.list()[1]
+        self.mock_cluster_get.return_value = cluster
+        self.mock_instance_get.return_value = self.databases.first()
+        self.mock_flavor_get.return_value = self.flavors.first()
+
+        details_url = reverse('horizon:project:database_clusters:detail',
+                              args=[cluster.id])
+        res = self.client.get(details_url)
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_cluster_get, 2,
+            mock.call(test.IsHttpRequest(), cluster.id))
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_instance_get, 3,
+            mock.call(test.IsHttpRequest(), test.IsA(str)))
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_flavor_get, 4,
+            mock.call(test.IsHttpRequest(), test.IsA(str)))
+        self.assertTemplateUsed(res, 'horizon/common/_detail.html')
+        self.assertNotContains(res, "Locality")
+
+    @test.create_mocks({trove_api.trove: ('cluster_get',
+                                          'instance_get',
+                                          'flavor_get',)})
+    def test_details_with_locality(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+        self.mock_instance_get.return_value = self.databases.first()
+        self.mock_flavor_get.return_value = self.flavors.first()
+
+        details_url = reverse('horizon:project:database_clusters:detail',
+                              args=[cluster.id])
+        res = self.client.get(details_url)
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_cluster_get, 2,
+            mock.call(test.IsHttpRequest(), cluster.id))
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_instance_get, 3,
+            mock.call(test.IsHttpRequest(), test.IsA(str)))
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_flavor_get, 4,
+            mock.call(test.IsHttpRequest(), test.IsA(str)))
+        self.assertTemplateUsed(res, 'project/database_clusters/'
+                                     '_detail_overview.html')
+        self.assertContains(res, "Location Policy")
+
+    @test.create_mocks(
+        {trove_api.trove: ('cluster_get',
+                           'cluster_grow'),
+         cluster_manager: ('get',)})
+    def test_grow_cluster(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+        cluster_volume = 1
+        flavor = self.flavors.first()
+        cluster_flavor = flavor.id
+        cluster_flavor_name = flavor.name
+        instances = [
+            cluster_manager.ClusterInstance("id1", "name1", cluster_flavor,
+                                            cluster_flavor_name,
+                                            cluster_volume, "master", None,
+                                            None),
+            cluster_manager.ClusterInstance("id2", "name2", cluster_flavor,
+                                            cluster_flavor_name,
+                                            cluster_volume, "slave",
+                                            "master", None),
+            cluster_manager.ClusterInstance("id3", None, cluster_flavor,
+                                            cluster_flavor_name,
+                                            cluster_volume, None, None, None),
+        ]
+
+        manager = cluster_manager.ClusterInstanceManager(cluster.id)
+        manager.instances = instances
+        self.mock_get.return_value = manager
+
+        url = reverse('horizon:project:database_clusters:cluster_grow_details',
+                      args=[cluster.id])
+        res = self.client.get(url)
+        self.assertTemplateUsed(
+            res, 'project/database_clusters/cluster_grow_details.html')
+        table = res.context_data[
+            "".join([tables.ClusterGrowInstancesTable.Meta.name, '_table'])]
+        self.assertEqual(len(cluster.instances), len(table.data))
+
+        action = "".join([tables.ClusterGrowInstancesTable.Meta.name, '__',
+                          tables.ClusterGrowRemoveInstance.name, '__',
+                          'id1'])
+        self.client.post(url, {'action': action})
+        self.assertEqual(len(cluster.instances) - 1, len(table.data))
+
+        action = "".join([tables.ClusterGrowInstancesTable.Meta.name, '__',
+                          tables.ClusterGrowAction.name, '__',
+                          cluster.id])
+        res = self.client.post(url, {'action': action})
+        self.mock_cluster_get.assert_called_once_with(
+            test.IsHttpRequest(), cluster.id)
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_get, 5, mock.call(cluster.id))
+        self.mock_cluster_grow.assert_called_once_with(
+            test.IsHttpRequest(), cluster.id, instances)
+        self.assertMessageCount(success=1)
+        self.assertRedirectsNoFollow(res, INDEX_URL)
+
+    @test.create_mocks({trove_api.trove: ('cluster_get',)})
+    def test_grow_cluster_no_instances(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+
+        url = reverse('horizon:project:database_clusters:cluster_grow_details',
+                      args=[cluster.id])
+        res = self.client.get(url)
+        self.assertTemplateUsed(
+            res, 'project/database_clusters/cluster_grow_details.html')
+
+        action = "".join([tables.ClusterGrowInstancesTable.Meta.name, '__',
+                          tables.ClusterGrowAction.name, '__',
+                          cluster.id])
+        self.client.post(url, {'action': action})
+        self.mock_cluster_get.assert_called_once_with(
+            test.IsHttpRequest(), cluster.id)
+        self.assertMessageCount(info=1)
+
+    @test.create_mocks(
+        {trove_api.trove: ('cluster_get',
+                           'cluster_grow',),
+         cluster_manager: ('get',)})
+    def test_grow_cluster_exception(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+        cluster_volume = 1
+        flavor = self.flavors.first()
+        cluster_flavor = flavor.id
+        cluster_flavor_name = flavor.name
+        instances = [
+            cluster_manager.ClusterInstance("id1", "name1", cluster_flavor,
+                                            cluster_flavor_name,
+                                            cluster_volume, "master", None,
+                                            None),
+            cluster_manager.ClusterInstance("id2", "name2", cluster_flavor,
+                                            cluster_flavor_name,
+                                            cluster_volume, "slave",
+                                            "master", None),
+            cluster_manager.ClusterInstance("id3", None, cluster_flavor,
+                                            cluster_flavor_name,
+                                            cluster_volume, None, None, None),
+        ]
+
+        manager = cluster_manager.ClusterInstanceManager(cluster.id)
+        manager.instances = instances
+        self.mock_get.return_value = manager
+        self.mock_cluster_grow.side_effect = self.exceptions.trove
+
+        url = reverse('horizon:project:database_clusters:cluster_grow_details',
+                      args=[cluster.id])
+        res = self.client.get(url)
+        self.assertTemplateUsed(
+            res, 'project/database_clusters/cluster_grow_details.html')
+
+        toSuppress = ["trove_dashboard.content.database_clusters.tables"]
+
+        # Suppress expected log messages in the test output
+        loggers = []
+        for cls in toSuppress:
+            logger = logging.getLogger(cls)
+            loggers.append((logger, logger.getEffectiveLevel()))
+            logger.setLevel(logging.CRITICAL)
+
+        try:
+            action = "".join([tables.ClusterGrowInstancesTable.Meta.name, '__',
+                              tables.ClusterGrowAction.name, '__',
+                              cluster.id])
+            res = self.client.post(url, {'action': action})
+
+            self.mock_cluster_get.assert_called_once_with(
+                test.IsHttpRequest(), cluster.id)
+            self.assert_mock_multiple_calls_with_same_arguments(
+                self.mock_get, 3, mock.call(cluster.id))
+            self.mock_cluster_grow.assert_called_once_with(
+                test.IsHttpRequest(), cluster.id, instances)
+            self.assertMessageCount(error=1)
+            self.assertRedirectsNoFollow(res, INDEX_URL)
+        finally:
+            # Restore the previous log levels
+            for (log, level) in loggers:
+                log.setLevel(level)
+
+    @test.create_mocks({trove_api.trove: ('cluster_get',
+                                          'cluster_shrink')})
+    def test_shrink_cluster(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+        instance_id = cluster.instances[0]['id']
+        cluster_instances = [{'id': instance_id}]
+
+        url = reverse(
+            'horizon:project:database_clusters:cluster_shrink_details',
+            args=[cluster.id])
+        res = self.client.get(url)
+        self.assertTemplateUsed(
+            res, 'project/database_clusters/cluster_shrink_details.html')
+        table = res.context_data[
+            "".join([tables.ClusterShrinkInstancesTable.Meta.name, '_table'])]
+        self.assertEqual(len(cluster.instances), len(table.data))
+
+        action = "".join([tables.ClusterShrinkInstancesTable.Meta.name, '__',
+                          tables.ClusterShrinkAction.name, '__',
+                          instance_id])
+        res = self.client.post(url, {'action': action})
+        self.assert_mock_multiple_calls_with_same_arguments(
+            self.mock_cluster_get, 2,
+            mock.call(test.IsHttpRequest(), cluster.id))
+        self.mock_cluster_shrink.assert_called_once_with(
+            test.IsHttpRequest(), cluster.id, cluster_instances)
+        self.assertNoFormErrors(res)
+        self.assertMessageCount(info=1)
+        self.assertRedirectsNoFollow(res, INDEX_URL)
+
+    @test.create_mocks({trove_api.trove: ('cluster_get',
+                                          'cluster_shrink')})
+    def test_shrink_cluster_exception(self):
+        cluster = self.trove_clusters.first()
+        self.mock_cluster_get.return_value = cluster
+        instance_id = cluster.instances[0]['id']
+        cluster_instances = [{'id': instance_id}]
+        self.mock_cluster_shrink.side_effect = self.exceptions.trove
+
+        url = reverse(
+            'horizon:project:database_clusters:cluster_shrink_details',
+            args=[cluster.id])
+        action = "".join([tables.ClusterShrinkInstancesTable.Meta.name, '__',
+                          tables.ClusterShrinkAction.name, '__',
+                          instance_id])
+
+        toSuppress = ["trove_dashboard.content.database_clusters.tables"]
+
+        # Suppress expected log messages in the test output
+        loggers = []
+        for cls in toSuppress:
+            logger = logging.getLogger(cls)
+            loggers.append((logger, logger.getEffectiveLevel()))
+            logger.setLevel(logging.CRITICAL)
+
+        try:
+            res = self.client.post(url, {'action': action})
+            self.mock_cluster_get.assert_called_once_with(
+                test.IsHttpRequest(), cluster.id)
+            self.mock_cluster_shrink.assert_called_once_with(
+                test.IsHttpRequest(), cluster.id, cluster_instances)
+            self.assertMessageCount(error=1)
+            self.assertRedirectsNoFollow(res, INDEX_URL)
+        finally:
+            # Restore the previous log levels
+            for (log, level) in loggers:
+                log.setLevel(level)
+
+    def _get_filtered_datastores(self, datastore):
+        filtered_datastore = []
+        for ds in self.datastores.list():
+            if datastore in ds.name:
+                filtered_datastore.append(ds)
+        return filtered_datastore
+
+    def _get_filtered_datastore_versions(self, datastores):
+        filtered_datastore_versions = []
+        for ds in datastores:
+            for dsv in self.datastore_versions.list():
+                if ds.id == dsv.datastore:
+                    filtered_datastore_versions.append(dsv)
+        return filtered_datastore_versions
+
+    def _contains_datastore_in_attribute(self, field, datastore):
+        for key, value in field.widget.attrs.items():
+            if datastore in key:
+                return True
+        return False
+
+    def _build_datastore_display_text(self, datastore, datastore_version):
+        return datastore + ' - ' + datastore_version
+
+    def _build_flavor_widget_name(self, datastore, datastore_version):
+        return common_utils.hexlify(self._build_datastore_display_text(
+            datastore, datastore_version))
diff -pruN 24.0.0-1/trove_dashboard/content/database_configurations/config_param_manager.py 25.0.0~rc1-1/trove_dashboard/content/database_configurations/config_param_manager.py
--- 24.0.0-1/trove_dashboard/content/database_configurations/config_param_manager.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_configurations/config_param_manager.py	2025-09-09 03:44:01.000000000 +0000
@@ -140,8 +140,8 @@ class Configuration(object):
 
 
 def validate_config_param_value(config_param, value):
-    if (config_param.type in (u"boolean", u"float", u"integer", u"long")):
-        if config_param.type == u"boolean":
+    if (config_param.type in ("boolean", "float", "integer", "long")):
+        if config_param.type == "boolean":
             if (value.lower() not in ("true", "false")):
                 return _('Value must be "true" or "false".')
         else:
diff -pruN 24.0.0-1/trove_dashboard/content/database_configurations/tables.py 25.0.0~rc1-1/trove_dashboard/content/database_configurations/tables.py
--- 24.0.0-1/trove_dashboard/content/database_configurations/tables.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_configurations/tables.py	2025-09-09 03:44:01.000000000 +0000
@@ -33,25 +33,27 @@ class CreateConfiguration(tables.LinkAct
     url = "horizon:project:database_configurations:create"
     classes = ('ajax-modal', )
     icon = "plus"
+    policy_rules = (("database", "configuration:create"),)
 
 
 class DeleteConfiguration(tables.DeleteAction):
     data_type_singular = _("Configuration Group")
     data_type_plural = _("Configuration Groups")
+    policy_rules = (("database", "configuration:delete"),)
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Configuration Group",
-            u"Delete Configuration Groups",
+            "Delete Configuration Group",
+            "Delete Configuration Groups",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Deleted Configuration Group",
-            u"Deleted Configuration Groups",
+            "Deleted Configuration Group",
+            "Deleted Configuration Groups",
             count
         )
 
@@ -87,6 +89,7 @@ class AddParameter(tables.LinkAction):
     url = "horizon:project:database_configurations:add"
     classes = ('ajax-modal', )
     icon = "plus"
+    policy_rules = (("database", "configuration:edit"),)
 
     def get_link_url(self, datum=None):
         configuration_id = self.table.kwargs['configuration_id']
@@ -98,6 +101,7 @@ class ApplyChanges(tables.Action):
     verbose_name = _("Apply Changes")
     verbose_name_plural = _("Apply Changes")
     icon = "pencil"
+    policy_rules = (("database", "configuration:edit"),)
 
     def __init__(self, **kwargs):
         super(ApplyChanges, self).__init__(**kwargs)
@@ -150,16 +154,16 @@ class DeleteParameter(tables.DeleteActio
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Parameter",
-            u"Delete Parameters",
+            "Delete Parameter",
+            "Delete Parameters",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Deleted Parameter",
-            u"Deleted Parameters",
+            "Deleted Parameter",
+            "Deleted Parameters",
             count
         )
 
@@ -205,16 +209,16 @@ class DetachConfiguration(tables.BatchAc
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Detach Configuration Group",
-            u"Detach Configuration Groups",
+            "Detach Configuration Group",
+            "Detach Configuration Groups",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Detached Configuration Group",
-            u"Detached Configuration Groups",
+            "Detached Configuration Group",
+            "Detached Configuration Groups",
             count
         )
 
diff -pruN 24.0.0-1/trove_dashboard/content/database_configurations/tests.py 25.0.0~rc1-1/trove_dashboard/content/database_configurations/tests.py
--- 24.0.0-1/trove_dashboard/content/database_configurations/tests.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/database_configurations/tests.py	2025-09-09 03:44:01.000000000 +0000
@@ -92,7 +92,7 @@ class DatabaseConfigurationsTests(test.T
     @test.create_mocks({
         api.trove: ('datastore_list', 'datastore_version_list',
                     'configuration_create')})
-    def _test_create_test_configuration(self, config_description=u''):
+    def _test_create_test_configuration(self, config_description=''):
         self.mock_datastore_list.return_value = self.datastores.list()
         self.mock_datastore_version_list.return_value = (
             self.datastore_versions.list())
@@ -100,7 +100,7 @@ class DatabaseConfigurationsTests(test.T
         self.mock_configuration_create.return_value = (
             self.database_configurations.first())
 
-        name = u'config1'
+        name = 'config1'
         values = "{}"
         ds = self._get_test_datastore('mysql')
         dsv = self._get_test_datastore_version(ds.id, '5.5')
@@ -129,7 +129,7 @@ class DatabaseConfigurationsTests(test.T
         self.assertMessageCount(success=1)
 
     def test_create_test_configuration(self):
-        self._test_create_test_configuration(u'description of config1')
+        self._test_create_test_configuration('description of config1')
 
     def test_create_test_configuration_with_no_description(self):
         self._test_create_test_configuration()
@@ -144,9 +144,9 @@ class DatabaseConfigurationsTests(test.T
 
         self.mock_configuration_create.side_effect = self.exceptions.trove
 
-        name = u'config1'
+        name = 'config1'
         values = "{}"
-        config_description = u'description of config1'
+        config_description = 'description of config1'
         ds = self._get_test_datastore('mysql')
         dsv = self._get_test_datastore_version(ds.id, '5.5')
         config_datastore = ds.name
diff -pruN 24.0.0-1/trove_dashboard/content/databases/forms.py 25.0.0~rc1-1/trove_dashboard/content/databases/forms.py
--- 24.0.0-1/trove_dashboard/content/databases/forms.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/forms.py	2025-09-09 03:44:01.000000000 +0000
@@ -188,7 +188,7 @@ class CreateUserForm(forms.SelfHandlingF
     def _get_databases(self, data):
         databases = []
         db_value = data['databases']
-        if db_value and db_value != u'':
+        if db_value and db_value != '':
             dbs = data['databases']
             databases = [{'name': d.strip()} for d in dbs.split(',')]
         return databases
diff -pruN 24.0.0-1/trove_dashboard/content/databases/logs/tables.py 25.0.0~rc1-1/trove_dashboard/content/databases/logs/tables.py
--- 24.0.0-1/trove_dashboard/content/databases/logs/tables.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/logs/tables.py	2025-09-09 03:44:01.000000000 +0000
@@ -25,20 +25,21 @@ class PublishLog(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Publish Log",
-            u"Publish Logs",
+            "Publish Log",
+            "Publish Logs",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Published Log",
-            u"Published Logs",
+            "Published Log",
+            "Published Logs",
             count
         )
 
     name = "publish_log"
+    policy_rules = (("database", "instance:guest_log_list"),)
 
     def action(self, request, obj_id):
         instance_id = self.table.kwargs['instance_id']
@@ -49,20 +50,21 @@ class DiscardLog(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Discard Log",
-            u"Discard Logs",
+            "Discard Log",
+            "Discard Logs",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Discarded Log",
-            u"Discarded Logs",
+            "Discarded Log",
+            "Discarded Logs",
             count
         )
 
     name = "discard_log"
+    policy_rules = (("database", "instance:guest_log_list"),)
 
     def action(self, request, obj_id):
         instance_id = self.table.kwargs['instance_id']
@@ -73,20 +75,21 @@ class EnableLog(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Enable Log",
-            u"Enable Logs",
+            "Enable Log",
+            "Enable Logs",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Enabled Log",
-            u"Enabled Logs",
+            "Enabled Log",
+            "Enabled Logs",
             count
         )
 
     name = "enable_log"
+    policy_rules = (("database", "instance:guest_log_list"),)
 
     def action(self, request, obj_id):
         instance_id = self.table.kwargs['instance_id']
@@ -97,20 +100,21 @@ class DisableLog(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Disable Log",
-            u"Disable Logs",
+            "Disable Log",
+            "Disable Logs",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Disabled Log",
-            u"Disabled Logs",
+            "Disabled Log",
+            "Disabled Logs",
             count
         )
 
     name = "disable_log"
+    policy_rules = (("database", "instance:guest_log_list"),)
 
     def action(self, request, obj_id):
         instance_id = self.table.kwargs['instance_id']
@@ -126,6 +130,7 @@ class ViewLog(tables.LinkAction):
     name = "view_log"
     verbose_name = _("View Log")
     url = "horizon:project:databases:logs:log_contents"
+    policy_rules = (("database", "instance:guest_log_list"),)
 
     def get_link_url(self, datum):
         instance_id = self.table.kwargs['instance_id']
diff -pruN 24.0.0-1/trove_dashboard/content/databases/logs/tests.py 25.0.0~rc1-1/trove_dashboard/content/databases/logs/tests.py
--- 24.0.0-1/trove_dashboard/content/databases/logs/tests.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/logs/tests.py	2025-09-09 03:44:01.000000000 +0000
@@ -111,7 +111,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('publish', log.name)
+        action_string = "logs__%s_log__%s" % ('publish', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -139,7 +139,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('publish', log.name)
+        action_string = "logs__%s_log__%s" % ('publish', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -167,7 +167,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('enable', log.name)
+        action_string = "logs__%s_log__%s" % ('enable', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -195,7 +195,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('enable', log.name)
+        action_string = "logs__%s_log__%s" % ('enable', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -223,7 +223,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('discard', log.name)
+        action_string = "logs__%s_log__%s" % ('discard', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -251,7 +251,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('discard', log.name)
+        action_string = "logs__%s_log__%s" % ('discard', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -279,7 +279,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('disable', log.name)
+        action_string = "logs__%s_log__%s" % ('disable', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -307,7 +307,7 @@ class LogsTests(test.TestCase):
         detail_url = reverse('horizon:project:databases:detail',
                              args=[database_id])
         url = detail_url + '?tab=instance_details__logs_tab'
-        action_string = u"logs__%s_log__%s" % ('disable', log.name)
+        action_string = "logs__%s_log__%s" % ('disable', log.name)
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -345,7 +345,6 @@ class LogsTests(test.TestCase):
             test.IsHttpRequest(),
             test.IsA(str),
             'guest.log',
-            False,
             LINES,
             self.mock_Connection())
         self.assertNoMessages()
@@ -376,7 +375,6 @@ class LogsTests(test.TestCase):
             test.IsHttpRequest(),
             test.IsA(str),
             'guest.log',
-            False,
             LINES,
             self.mock_Connection())
         self.assertContains(res, "Unable to load")
diff -pruN 24.0.0-1/trove_dashboard/content/databases/logs/views.py 25.0.0~rc1-1/trove_dashboard/content/databases/logs/views.py
--- 24.0.0-1/trove_dashboard/content/databases/logs/views.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/logs/views.py	2025-09-09 03:44:01.000000000 +0000
@@ -46,17 +46,15 @@ class LogContentsView(generic.TemplateVi
         context["log_contents"] = get_contents(self.request,
                                                kwargs['instance_id'],
                                                kwargs['filename'],
-                                               False,
                                                log_length)
         return context
 
 
-def get_contents(request, instance_id, filename, publish, lines):
+def get_contents(request, instance_id, filename, lines):
     try:
         log_generator = api.trove.log_tail(request,
                                            instance_id,
                                            filename,
-                                           publish,
                                            lines,
                                            dash_api.swift.swift_api(request))
         data = ""
@@ -71,16 +69,10 @@ def build_response(request, instance_id,
     data = (_('Unable to load {0} log for instance "{1}".')
             .format(filename, instance_id))
 
-    if request.GET.get('publish'):
-        publish = True
-    else:
-        publish = False
-
     try:
         data = get_contents(request,
                             instance_id,
                             filename,
-                            publish,
                             int(tail))
     except Exception:
         exceptions.handle(request, ignore=True)
@@ -106,16 +98,9 @@ def full_log(request, instance_id, filen
 
 def download_log(request, instance_id, filename):
     try:
-        publish_value = request.GET.get('publish')
-        if publish_value:
-            publish = True
-        else:
-            publish = False
-
         data = get_contents(request,
                             instance_id,
                             filename,
-                            publish,
                             FULL_LOG_VALUE)
         response = http.HttpResponse()
         response.write(data)
diff -pruN 24.0.0-1/trove_dashboard/content/databases/tables.py 25.0.0~rc1-1/trove_dashboard/content/databases/tables.py
--- 24.0.0-1/trove_dashboard/content/databases/tables.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/tables.py	2025-09-09 03:44:01.000000000 +0000
@@ -42,20 +42,21 @@ ACTIVE_STATES = ("ACTIVE", "HEALTHY",)
 
 class DeleteInstance(tables.DeleteAction):
     help_text = _("Deleted instances are not recoverable.")
+    policy_rules = (("database", "instance:delete"),)
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Instance",
-            u"Delete Instances",
+            "Delete Instance",
+            "Delete Instances",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Scheduled deletion of Instance",
-            u"Scheduled deletion of Instances",
+            "Scheduled deletion of Instance",
+            "Scheduled deletion of Instances",
             count
         )
 
@@ -66,20 +67,21 @@ class DeleteInstance(tables.DeleteAction
 class RestartInstance(tables.BatchAction):
     help_text = _("Restarted instances will lose any data not"
                   " saved in persistent storage.")
+    policy_rules = (("database", "instance:restart"),)
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Restart Instance",
-            u"Restart Instances",
+            "Restart Instance",
+            "Restart Instances",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Restarted Instance",
-            u"Restarted Instances",
+            "Restarted Instance",
+            "Restarted Instances",
             count
         )
 
@@ -99,16 +101,17 @@ class DetachReplica(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Detach Replica",
-            u"Detach Replicas",
+            "Detach Replica",
+            "Detach Replicas",
             count
         )
+    policy_rules = (("database", "instance:eject_replica_source"),)
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Replica Detached",
-            u"Replicas Detached",
+            "Replica Detached",
+            "Replicas Detached",
             count
         )
 
@@ -128,6 +131,7 @@ class PromoteToReplicaSource(tables.Link
     verbose_name = _("Promote to Replica Source")
     url = "horizon:project:databases:promote_to_replica_source"
     classes = ("ajax-modal", "btn-promote-to-replica-source")
+    policy_rules = (("database", "instance:promote_to_replica_source"),)
 
     def allowed(self, request, instance=None):
         return (instance.status in ACTIVE_STATES and
@@ -142,21 +146,22 @@ class EjectReplicaSource(tables.BatchAct
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Eject Replica Source",
-            u"Eject Replica Sources",
+            "Eject Replica Source",
+            "Eject Replica Sources",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Ejected Replica Source",
-            u"Ejected Replica Sources",
+            "Ejected Replica Source",
+            "Ejected Replica Sources",
             count
         )
 
     name = "eject_replica_source"
     classes = ('btn-danger', 'btn-eject-replica-source')
+    policy_rules = (("database", "instance:eject_replica_source"),)
 
     def _allowed(self, request, instance=None):
         return (instance.status != 'PROMOTE' and
@@ -170,21 +175,22 @@ class GrantAccess(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Grant Access",
-            u"Grant Access",
+            "Grant Access",
+            "Grant Access",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Granted Access to",
-            u"Granted Access to",
+            "Granted Access to",
+            "Granted Access to",
             count
         )
 
     name = "grant_access"
     classes = ('btn-grant-access')
+    policy_rules = (("database", "instance:extension:user_access:update"),)
 
     def allowed(self, request, instance=None):
         if instance:
@@ -204,21 +210,22 @@ class RevokeAccess(tables.BatchAction):
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Revoke Access",
-            u"Revoke Access",
+            "Revoke Access",
+            "Revoke Access",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Access Revoked to",
-            u"Access Revoked to",
+            "Access Revoked to",
+            "Access Revoked to",
             count
         )
 
     name = "revoke_access"
     classes = ('btn-revoke-access')
+    policy_rules = (("database", "instance:extension:user_access:delete"),)
 
     def allowed(self, request, instance=None):
         if instance:
@@ -246,6 +253,7 @@ def parse_host_param(request):
 
 class AccessTable(tables.DataTable):
     dbname = tables.Column("name", verbose_name=_("Name"))
+
     access = tables.Column(
         "access",
         verbose_name=_("Accessible"),
@@ -265,6 +273,7 @@ class ManageAccess(tables.LinkAction):
     verbose_name = _("Manage Access")
     url = "horizon:project:databases:access_detail"
     icon = "pencil"
+    policy_rules = (("database", "instance:extension:user_access:update"),)
 
     def allowed(self, request, instance=None):
         instance = self.table.kwargs['instance']
@@ -284,6 +293,7 @@ class CreateUser(tables.LinkAction):
     url = "horizon:project:databases:create_user"
     classes = ("ajax-modal",)
     icon = "plus"
+    policy_rules = (("database", "instance:extension:user:create"),)
 
     def allowed(self, request, instance=None):
         instance = self.table.kwargs['instance']
@@ -301,6 +311,7 @@ class EditUser(tables.LinkAction):
     url = "horizon:project:databases:edit_user"
     classes = ("ajax-modal",)
     icon = "pencil"
+    policy_rules = (("database", "instance:extension:user:update"),)
 
     def allowed(self, request, instance=None):
         instance = self.table.kwargs['instance']
@@ -322,19 +333,21 @@ def has_user_add_perm(request):
 
 
 class DeleteUser(tables.DeleteAction):
+    policy_rules = (("database", "instance:extension:user:delete"),)
+
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete User",
-            u"Delete Users",
+            "Delete User",
+            "Delete Users",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Deleted User",
-            u"Deleted Users",
+            "Deleted User",
+            "Deleted Users",
             count
         )
 
@@ -350,6 +363,7 @@ class CreateDatabase(tables.LinkAction):
     url = "horizon:project:databases:create_database"
     classes = ("ajax-modal",)
     icon = "plus"
+    policy_rules = (("database", "instance:extension:database:create"),)
 
     def allowed(self, request, database=None):
         instance = self.table.kwargs['instance']
@@ -369,19 +383,21 @@ def has_database_add_perm(request):
 
 
 class DeleteDatabase(tables.DeleteAction):
+    policy_rules = (("database", "instance:extension:database:delete"),)
+
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Delete Database",
-            u"Delete Databases",
+            "Delete Database",
+            "Delete Databases",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Deleted Database",
-            u"Deleted Databases",
+            "Deleted Database",
+            "Deleted Databases",
             count
         )
 
@@ -400,6 +416,7 @@ class LaunchLink(tables.LinkAction):
     url = "horizon:project:databases:launch"
     classes = ("ajax-modal", "btn-launch")
     icon = "cloud-upload"
+    policy_rules = (("database", "instance:create"),)
 
 
 class CreateBackup(tables.LinkAction):
@@ -408,6 +425,7 @@ class CreateBackup(tables.LinkAction):
     url = "horizon:project:database_backups:create"
     classes = ("ajax-modal",)
     icon = "camera"
+    policy_rules = (("database", "backup:create"),)
 
     def allowed(self, request, instance=None):
         return (instance.status in ACTIVE_STATES and
@@ -423,6 +441,7 @@ class ResizeVolume(tables.LinkAction):
     verbose_name = _("Resize Volume")
     url = "horizon:project:databases:resize_volume"
     classes = ("ajax-modal", "btn-resize")
+    policy_rules = (("database", "instance:resize_volume"),)
 
     def allowed(self, request, instance=None):
         return instance.status in ACTIVE_STATES
@@ -437,6 +456,7 @@ class ResizeInstance(tables.LinkAction):
     verbose_name = _("Resize Instance")
     url = "horizon:project:databases:resize_instance"
     classes = ("ajax-modal", "btn-resize")
+    policy_rules = (("database", "instance:resize_flavor"),)
 
     def allowed(self, request, instance=None):
         return ((instance.status in ACTIVE_STATES or
@@ -452,6 +472,7 @@ class AttachConfiguration(tables.LinkAct
     verbose_name = _("Attach Configuration Group")
     url = "horizon:project:databases:attach_config"
     classes = ("btn-attach-config", "ajax-modal")
+    policy_rules = (("database", "instance:update"),)
 
     def allowed(self, request, instance=None):
         return (instance.status in ACTIVE_STATES and
@@ -462,21 +483,22 @@ class DetachConfiguration(tables.BatchAc
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Detach Configuration Group",
-            u"Detach Configuration Groups",
+            "Detach Configuration Group",
+            "Detach Configuration Groups",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Detached Configuration Group",
-            u"Detached Configuration Groups",
+            "Detached Configuration Group",
+            "Detached Configuration Groups",
             count
         )
 
     name = "detach_configuration"
     classes = ('btn-danger', 'btn-detach-config')
+    policy_rules = (("database", "instance:update"),)
 
     def allowed(self, request, instance=None):
         return (instance.status in ACTIVE_STATES and
@@ -489,6 +511,7 @@ class DetachConfiguration(tables.BatchAc
 class EnableRootAction(tables.Action):
     name = "enable_root_action"
     verbose_name = _("Enable Root")
+    policy_rules = (("database", "instance:extension:root:create"),)
 
     def handle(self, table, request, obj_ids):
         try:
@@ -502,6 +525,7 @@ class EnableRootAction(tables.Action):
 class DisableRootAction(tables.Action):
     name = "disable_root_action"
     verbose_name = _("Disable Root")
+    policy_rules = (("database", "instance:extension:root:delete"),)
 
     def allowed(self, request, instance):
         enabled = api.trove.root_show(request, instance.id)
@@ -521,6 +545,9 @@ class ManageRoot(tables.LinkAction):
     name = "manage_root_action"
     verbose_name = _("Manage Root Access")
     url = "horizon:project:databases:manage_root"
+    policy_rules = (("database", "instance:extension:root:index"),
+                    ("database", "instance:extension:root:create"),
+                    ("database", "instance:extension:root:delete"))
 
     def allowed(self, request, instance):
         return instance.status in ACTIVE_STATES
@@ -532,6 +559,7 @@ class ManageRoot(tables.LinkAction):
 
 class ManageRootTable(tables.DataTable):
     name = tables.Column('name', verbose_name=_('Instance Name'))
+    policy_rules = (("database", "instance:extension:root:index"), )
     enabled = tables.Column('enabled',
                             verbose_name=_('Has Root Ever Been Enabled'),
                             filters=(d_filters.yesno, d_filters.capfirst),
@@ -659,20 +687,21 @@ class StopDatabase(tables.BatchAction):
     name = "stop_database"
     help_text = _("Stop database service inside an instance.")
     action_type = "danger"
+    policy_rules = (("database", "instance:extension:database:delete"), )
 
     @staticmethod
     def action_present(count):
         return ngettext_lazy(
-            u"Stop Database Service",
-            u"Stop Database Services",
+            "Stop Database Service",
+            "Stop Database Services",
             count
         )
 
     @staticmethod
     def action_past(count):
         return ngettext_lazy(
-            u"Database Service stopped",
-            u"Database Services stopped",
+            "Database Service stopped",
+            "Database Services stopped",
             count
         )
 
@@ -688,6 +717,7 @@ class UpdateInstance(tables.LinkAction):
     verbose_name = _("Update Instance")
     url = "horizon:project:databases:edit_instance"
     classes = ("btn-attach-config", "ajax-modal")
+    policy_rules = (("database", "instance:update"), )
 
     def allowed(self, request, instance=None):
         return (instance.status in ACTIVE_STATES)
@@ -709,28 +739,28 @@ class InstancesTable(tables.DataTable):
     )
     STATUS_DISPLAY_CHOICES = (
         ("ACTIVE", pgettext_lazy("Current status of a Database Instance",
-                                 u"Active")),
+                                 "Active")),
         ("Healthy", pgettext_lazy("Current status of a Database Instance",
-                                  u"Healthy")),
+                                  "Healthy")),
         ("BLOCKED", pgettext_lazy("Current status of a Database Instance",
-                                  u"Blocked")),
+                                  "Blocked")),
         ("BUILD", pgettext_lazy("Current status of a Database Instance",
-                                u"Building")),
+                                "Building")),
         ("FAILED", pgettext_lazy("Current status of a Database Instance",
-                                 u"Failed")),
+                                 "Failed")),
         ("REBOOT", pgettext_lazy("Current status of a Database Instance",
-                                 u"Rebooting")),
+                                 "Rebooting")),
         ("RESIZE", pgettext_lazy("Current status of a Database Instance",
-                                 u"Resizing")),
+                                 "Resizing")),
         ("BACKUP", pgettext_lazy("Current status of a Database Instance",
-                                 u"Backup")),
+                                 "Backup")),
         ("SHUTDOWN", pgettext_lazy("Current status of a Database Instance",
-                                   u"Shutdown")),
+                                   "Shutdown")),
         ("ERROR", pgettext_lazy("Current status of a Database Instance",
-                                u"Error")),
+                                "Error")),
         ("RESTART_REQUIRED",
          pgettext_lazy("Current status of a Database Instance",
-                       u"Restart Required")),
+                       "Restart Required")),
     )
     name = tables.Column("name",
                          link="horizon:project:databases:detail",
diff -pruN 24.0.0-1/trove_dashboard/content/databases/templates/databases/_detail_overview.html 25.0.0~rc1-1/trove_dashboard/content/databases/templates/databases/_detail_overview.html
--- 24.0.0-1/trove_dashboard/content/databases/templates/databases/_detail_overview.html	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/templates/databases/_detail_overview.html	2025-09-09 03:44:01.000000000 +0000
@@ -25,7 +25,7 @@
     <dt>{% trans "Root Enabled" %}</dt>
     <dd>{{ root_enabled|capfirst }}</dd>
     {% if instance.locality %}
-      <dt>{% trans "Locality" %}</dt>
+      <dt>{% trans "Location Policy" %}</dt>
       <dd>{{ instance.locality }}</dd>
     {% endif %}
   </dl>
diff -pruN 24.0.0-1/trove_dashboard/content/databases/templates/databases/_resize_volume.html 25.0.0~rc1-1/trove_dashboard/content/databases/templates/databases/_resize_volume.html
--- 24.0.0-1/trove_dashboard/content/databases/templates/databases/_resize_volume.html	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/templates/databases/_resize_volume.html	2025-09-09 03:44:01.000000000 +0000
@@ -3,5 +3,5 @@
 
 {% block modal-body-right %}
   <p>{% trans "Specify the new volume size for the database instance." %}</p>
-  <p><strong>{% trans "Please note:</strong> The new value must be greater than the existing volume size." %}</strong></p>
+  <p><strong>{% trans "Please note: The new value must be greater than the existing volume size." %}</strong></p>
 {% endblock %}
diff -pruN 24.0.0-1/trove_dashboard/content/databases/templates/databases/logs/view_log.html 25.0.0~rc1-1/trove_dashboard/content/databases/templates/databases/logs/view_log.html
--- 24.0.0-1/trove_dashboard/content/databases/templates/databases/logs/view_log.html	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/templates/databases/logs/view_log.html	2025-09-09 03:44:01.000000000 +0000
@@ -3,7 +3,7 @@
 {% block title %}{% trans "Log" %}{% endblock %}
 
 {% block page_header %}
-  {% include "horizon/common/_page_header.html" with title=_("Log: ")|add:filename %}
+  {% include "horizon/common/_page_header.html" with title=_("Log:")|add:" "|add:filename %}
 {% endblock page_header %}
 
 {% block main %}
diff -pruN 24.0.0-1/trove_dashboard/content/databases/tests.py 25.0.0~rc1-1/trove_dashboard/content/databases/tests.py
--- 24.0.0-1/trove_dashboard/content/databases/tests.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/tests.py	2025-09-09 03:44:01.000000000 +0000
@@ -437,11 +437,11 @@ class DatabaseTests(test.TestCase):
 
     def test_details_without_locality(self):
         database = self.databases.list()[1]
-        self._test_details(database, "Locality", assert_contains=False)
+        self._test_details(database, "Location Policy", assert_contains=False)
 
     def test_details_with_locality(self):
         database = self.databases.first()
-        self._test_details(database, "Locality")
+        self._test_details(database, "Location Policy")
 
     def test_create_database(self):
         database = self.databases.first()
@@ -488,8 +488,8 @@ class DatabaseTests(test.TestCase):
 
         res = self.client.post(url, post)
         self.mock_database_create.assert_called_once_with(
-            test.IsHttpRequest(), u'id', u'NewDB', character_set=u'',
-            collation=u'')
+            test.IsHttpRequest(), 'id', 'NewDB', character_set='',
+            collation='')
         self.assertNoFormErrors(res)
         self.assertMessageCount(success=1)
 
@@ -506,14 +506,14 @@ class DatabaseTests(test.TestCase):
 
         res = self.client.post(url, post)
         self.mock_database_create.assert_called_once_with(
-            test.IsHttpRequest(), u'id', u'NewDB', character_set=u'',
-            collation=u'')
+            test.IsHttpRequest(), 'id', 'NewDB', character_set='',
+            collation='')
         self.assertEqual(res.status_code, 302)
 
     @test.create_mocks({api.trove: ('instance_get', 'root_show')})
     def test_show_root(self):
         database = self.databases.first()
-        database.id = u'id'
+        database.id = 'id'
         user = self.database_user_roots.first()
 
         self.mock_instance_get.return_value = database
@@ -543,7 +543,7 @@ class DatabaseTests(test.TestCase):
         self.mock_instance_get.assert_called_once_with(
             test.IsHttpRequest(), test.IsA(str))
         self.mock_root_show.assert_called_once_with(
-            test.IsHttpRequest(), u'id')
+            test.IsHttpRequest(), 'id')
         self.assertRedirectsNoFollow(res, DETAILS_URL)
 
     @test.create_mocks({api.trove: ('root_enable',)})
@@ -565,7 +565,7 @@ class DatabaseTests(test.TestCase):
         table.maybe_handle()
 
         self.mock_root_enable.assert_called_once_with(
-            test.IsHttpRequest(), [u'id'])
+            test.IsHttpRequest(), ['id'])
         self.assertEqual(table.data[0].enabled, True)
         self.assertEqual(table.data[0].password, "password")
 
@@ -588,7 +588,7 @@ class DatabaseTests(test.TestCase):
         table.maybe_handle()
 
         self.mock_root_enable.assert_called_once_with(
-            test.IsHttpRequest(), [u'id'])
+            test.IsHttpRequest(), ['id'])
         self.assertNotEqual(table.data[0].enabled, True)
         self.assertNotEqual(table.data[0].password, "password")
 
@@ -610,7 +610,7 @@ class DatabaseTests(test.TestCase):
         table.maybe_handle()
 
         self.mock_root_disable.assert_called_once_with(
-            test.IsHttpRequest(), u'id')
+            test.IsHttpRequest(), 'id')
         self.assertEqual(table.data[0].enabled, True)
         self.assertIsNone(table.data[0].password)
 
@@ -634,7 +634,7 @@ class DatabaseTests(test.TestCase):
         table.maybe_handle()
 
         self.mock_root_disable.assert_called_once_with(
-            test.IsHttpRequest(), u'id')
+            test.IsHttpRequest(), 'id')
         self.assertEqual(table.data[0].enabled, True)
         self.assertEqual(table.data[0].password, "password")
 
@@ -665,7 +665,7 @@ class DatabaseTests(test.TestCase):
         details_url = reverse('horizon:project:databases:detail',
                               args=[database_id])
         url = details_url + '?tab=instance_details__users_tab'
-        action_string = u"users__delete__%s" % user_id
+        action_string = "users__delete__%s" % user_id
         form_data = {'action': action_string}
         res = self.client.post(url, form_data)
         self.mock_instance_get.assert_called_once_with(
@@ -713,8 +713,8 @@ class DatabaseTests(test.TestCase):
 
         res = self.client.post(url, post)
         self.mock_user_create.assert_called_once_with(
-            test.IsHttpRequest(), database.id, user.name, u'password',
-            host=u'', databases=[])
+            test.IsHttpRequest(), database.id, user.name, 'password',
+            host='', databases=[])
         self.assertNoFormErrors(res)
         self.assertMessageCount(success=1)
 
@@ -732,8 +732,8 @@ class DatabaseTests(test.TestCase):
 
         res = self.client.post(url, post)
         self.mock_user_create.assert_called_once_with(
-            test.IsHttpRequest(), u'id', u'name', u'password',
-            host=u'', databases=[])
+            test.IsHttpRequest(), 'id', 'name', 'password',
+            host='', databases=[])
         self.assertEqual(res.status_code, 302)
 
     @test.create_mocks({api.trove: ('user_update_attributes',)})
diff -pruN 24.0.0-1/trove_dashboard/content/databases/workflows/create_instance.py 25.0.0~rc1-1/trove_dashboard/content/databases/workflows/create_instance.py
--- 24.0.0-1/trove_dashboard/content/databases/workflows/create_instance.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/content/databases/workflows/create_instance.py	2025-09-09 03:44:01.000000000 +0000
@@ -113,7 +113,7 @@ class SetInstanceDetailsAction(workflows
                                                        **kwargs)
         # Add this field to the end after the dynamic fields
         self.fields['locality'] = forms.ChoiceField(
-            label=_("Locality"),
+            label=_("Location Policy"),
             choices=[("", "None"),
                      ("affinity", "affinity"),
                      ("anti-affinity", "anti-affinity")],
diff -pruN 24.0.0-1/trove_dashboard/enabled/_1710_database_panel_group.py 25.0.0~rc1-1/trove_dashboard/enabled/_1710_database_panel_group.py
--- 24.0.0-1/trove_dashboard/enabled/_1710_database_panel_group.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/enabled/_1710_database_panel_group.py	2025-09-09 03:44:01.000000000 +0000
@@ -15,6 +15,6 @@ from django.utils.translation import get
 # The slug of the panel group to be added to HORIZON_CONFIG. Required.
 PANEL_GROUP = 'database'
 # The display name of the PANEL_GROUP. Required.
-PANEL_GROUP_NAME = _('Database')
+PANEL_GROUP_NAME = _('Databases')
 # The slug of the dashboard the PANEL_GROUP associated with. Required.
 PANEL_GROUP_DASHBOARD = 'project'
diff -pruN 24.0.0-1/trove_dashboard/enabled/_1740_project_database_clusters_panel.py 25.0.0~rc1-1/trove_dashboard/enabled/_1740_project_database_clusters_panel.py
--- 24.0.0-1/trove_dashboard/enabled/_1740_project_database_clusters_panel.py	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/enabled/_1740_project_database_clusters_panel.py	2025-09-09 03:44:01.000000000 +0000
@@ -22,7 +22,7 @@ PANEL_DASHBOARD = 'project'
 # The slug of the panel group the PANEL is associated with.
 PANEL_GROUP = 'database'
 
-DISABLED = True
+DISABLED = False
 
 # Python panel class of the PANEL to be added.
 ADD_PANEL = 'trove_dashboard.content.database_clusters.panel.Clusters'
diff -pruN 24.0.0-1/trove_dashboard/locale/cs/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/cs/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/cs/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/cs/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -4,7 +4,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2021-03-03 00:05+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -510,9 +510,6 @@ msgstr "Délka logu"
 msgid "Log length must be a nonnegative integer."
 msgstr "Délka logu musí být nezáporné celé číslo."
 
-msgid "Log: "
-msgstr "Log: "
-
 msgid "Logs"
 msgstr "Logy"
 
@@ -605,12 +602,6 @@ msgstr "Počet částí"
 msgid "Number of instances in the cluster."
 msgstr "Počet instancí v clusteru."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Počet instanci v clusteru (pouze pro čtení)."
-
-msgid "Number of shards. (Read only)"
-msgstr "Počet částí. (Pouze pro čtení)"
-
 msgid "Old Flavor"
 msgstr "Původní typ"
 
@@ -692,13 +683,6 @@ msgid ""
 msgstr ""
 "Heslo je viditelné pouze bezprostředně po povolení nebo resetování root."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Nezapomeňte prosím:</strong> Nová hodnota musí být větší nebo rovna "
-"velikosti původního svazku."
-
 msgid "Promote"
 msgstr "Povýšení"
 
@@ -1059,6 +1043,7 @@ msgstr "Nelze vypsat zálohy databáze p
 msgid "Unable to list database instances to backup."
 msgstr "Nelze vypsat instance databáze k zálohování."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1066,6 +1051,7 @@ msgstr ""
 "Nelze načíst  {0} log.\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "Nelze načíst  {0} log pro instanci \"{1}\"."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/de/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/de/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/de/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/de/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -618,9 +618,6 @@ msgstr "%(count)s mal \"%(name)s\" gesta
 msgid "Launched cluster \"%s\""
 msgstr "Cluster \"%s\" gestartet"
 
-msgid "Locality"
-msgstr "Lokalität"
-
 msgid "Log"
 msgstr "Log"
 
@@ -633,9 +630,6 @@ msgstr "Loglänge"
 msgid "Log length must be a nonnegative integer."
 msgstr "Loglänge muß eine nichtnegative Zahl sein."
 
-msgid "Log: "
-msgstr "Log:"
-
 msgid "Logs"
 msgstr "Logs"
 
@@ -756,12 +750,6 @@ msgstr "Anzahl der Shards"
 msgid "Number of instances in the cluster."
 msgstr "Anzahl der Instanzen in dem Cluster."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Anzahl der Instanzen im Cluster (nur lesen)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Anzahl der Shards. (nur lesen)"
-
 msgid "Old Flavor"
 msgstr "Alte Variante"
 
@@ -854,13 +842,6 @@ msgid ""
 msgstr ""
 "Passwort ist nur sichtbar, nachdem Root aktiviert oder zurückgesetzt ist."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Bitte beachten:</strong> Der neue Wert muss grösser sein als die "
-"existierende Datenträgergrösse."
-
 msgid "Promote"
 msgstr "Befördern"
 
@@ -1268,6 +1249,7 @@ msgstr "Eltern-Datenbank-Sicherungskopie
 msgid "Unable to list database instances to backup."
 msgstr "Die zu sichernden Datenbankinstanzen können nicht aufgelistet werden."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1275,6 +1257,7 @@ msgstr ""
 "Konnte log {0} nicht laden\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "Konnte log {0} für Instanz \"{1}\" nicht laden."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/en_GB/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/en_GB/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/en_GB/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/en_GB/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -697,9 +697,6 @@ msgstr "Launched %(count)s named \"%(nam
 msgid "Launched cluster \"%s\""
 msgstr "Launched cluster \"%s\""
 
-msgid "Locality"
-msgstr "Locality"
-
 msgid "Log"
 msgstr "Log"
 
@@ -712,9 +709,6 @@ msgstr "Log Length"
 msgid "Log length must be a nonnegative integer."
 msgstr "Log length must be a non-negative integer."
 
-msgid "Log: "
-msgstr "Log: "
-
 msgid "Logs"
 msgstr "Logs"
 
@@ -846,12 +840,6 @@ msgstr "Number of Shards"
 msgid "Number of instances in the cluster."
 msgstr "Number of instances in the cluster."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Number of instances in the cluster. (Read only)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Number of shards. (Read only)"
-
 msgid "Old Flavor"
 msgstr "Old Flavour"
 
@@ -941,13 +929,6 @@ msgid ""
 msgstr ""
 "Password is only visible immediately after the root is enabled or reset."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-
 msgid "Project"
 msgstr "Project"
 
@@ -1405,6 +1386,7 @@ msgstr "Unable to list database backups
 msgid "Unable to list database instances to backup."
 msgstr "Unable to list database instances to backup."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1412,6 +1394,7 @@ msgstr ""
 "Unable to load {0} log\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "Unable to load {0} log for instance \"{1}\"."
 
@@ -1621,6 +1604,3 @@ msgstr ""
 
 msgid "instance"
 msgstr "instance"
-
-msgid "instance_id"
-msgstr "instance_id"
diff -pruN 24.0.0-1/trove_dashboard/locale/fr/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/fr/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/fr/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/fr/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -623,9 +623,6 @@ msgstr "%(count)s instance(s) nommée(s)
 msgid "Launched cluster \"%s\""
 msgstr "Cluster \"%s\" démarré"
 
-msgid "Locality"
-msgstr "Localisation"
-
 msgid "Log"
 msgstr "Journal"
 
@@ -638,9 +635,6 @@ msgstr "Longueur du journal"
 msgid "Log length must be a nonnegative integer."
 msgstr "La longueur du journal doit correspondre à un nombre non négatif."
 
-msgid "Log: "
-msgstr "Journal :"
-
 msgid "Logs"
 msgstr "Journaux"
 
@@ -761,12 +755,6 @@ msgstr "Nombre de fragments"
 msgid "Number of instances in the cluster."
 msgstr "Nombre d'instances dans le cluster."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Nombre d'instances dans le cluster. (En lecture seule)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Nombre de fragments. (lecture seule)"
-
 msgid "Old Flavor"
 msgstr "Ancien gabarit"
 
@@ -860,13 +848,6 @@ msgstr ""
 "Le mot de passe est visible uniquement juste après l'activation de root ou "
 "sa réinitialisation."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Veuillez noter que :</strong> La nouvelle valeur doit être plus grande que "
-"la taille du volume existant."
-
 msgid "Promote"
 msgstr "Promouvoir"
 
@@ -1275,6 +1256,7 @@ msgstr "Impossible de lister les sauvega
 msgid "Unable to list database instances to backup."
 msgstr "Impossible de lister les instances de base de données à sauvegarder."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1282,6 +1264,7 @@ msgstr ""
 "Impossible de charger le journal {0}\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "Impossible de charger le journal {0} pour l\\'instance \"{1}\"."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/id/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/id/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/id/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/id/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -4,7 +4,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -582,9 +582,6 @@ msgstr "Diluncurkan %(count)s named \"%(
 msgid "Launched cluster \"%s\""
 msgstr "Diluncurkan klaster \"%s\""
 
-msgid "Locality"
-msgstr "Locality (lokalitas)"
-
 msgid "Log"
 msgstr "Log (catatan)"
 
@@ -597,9 +594,6 @@ msgstr "Log Length (panjang catatan)"
 msgid "Log length must be a nonnegative integer."
 msgstr "Panjang log harus berupa bilangan integer positif."
 
-msgid "Log: "
-msgstr "Log (catatan): "
-
 msgid "Logs"
 msgstr "Logs (catatan)"
 
@@ -713,12 +707,6 @@ msgstr "Number of Shards (jumlah serpiha
 msgid "Number of instances in the cluster."
 msgstr "Jumlah instance dalam cluster."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Jumlah instance dalam cluster. (read only)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Jumlah serpihan. (Read only)"
-
 msgid "Old Flavor"
 msgstr "Old Flavor (flavor lama)"
 
@@ -808,13 +796,6 @@ msgid ""
 "Password is only visible immediately after the root is enabled or reset."
 msgstr "Password hanya terlihat segera setelah akar diaktifkan atau reset."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Harap dicatat:</strong> Nilai baru harus lebih besar dari ukuran volume yang "
-"ada."
-
 msgid "Promote"
 msgstr "Promote (promosi)"
 
@@ -1200,6 +1181,7 @@ msgstr "Tidak dapat mendaftar backup dat
 msgid "Unable to list database instances to backup."
 msgstr "Tidak dapat mendaftar instance database untuk backup."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1207,6 +1189,7 @@ msgstr ""
 "Tidak bisa memuat {0} log\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "Tidak bisa memuat {0} log untuk instance \"{1}\"."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/ja/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/ja/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/ja/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/ja/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -552,9 +552,6 @@ msgstr "名前が \"%(name)s\" の %(cou
 msgid "Launched cluster \"%s\""
 msgstr "クラスター \"%s\" を起動しました。"
 
-msgid "Locality"
-msgstr "局所性"
-
 msgid "Log"
 msgstr "ログ"
 
@@ -567,9 +564,6 @@ msgstr "ログの表示行数"
 msgid "Log length must be a nonnegative integer."
 msgstr "ログの表示行数は 0 以上の整数でなければいけません。"
 
-msgid "Log: "
-msgstr "ログ:"
-
 msgid "Logs"
 msgstr "ログ"
 
@@ -680,12 +674,6 @@ msgstr "シャード数"
 msgid "Number of instances in the cluster."
 msgstr "クラスター内のインスタンス数。"
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "クラスターのインスタンス数 (読み出し専用)"
-
-msgid "Number of shards. (Read only)"
-msgstr "シャード数 (読み出し専用)"
-
 msgid "Old Flavor"
 msgstr "現在のフレーバー"
 
@@ -775,13 +763,6 @@ msgid ""
 msgstr ""
 "パスワードが表示されるのは、ルートを有効またはリセットした直後のみです。"
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"注意</strong>: 新しいボリュームサイズは現在のサイズよりも大きくなければいけま"
-"せん。"
-
 msgid "Promote"
 msgstr "昇格"
 
@@ -1163,6 +1144,7 @@ msgstr "親バックアップとなる
 msgid "Unable to list database instances to backup."
 msgstr "バックアップ候補のデータベースインスタンスの一覧を取得できません。"
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1170,6 +1152,7 @@ msgstr ""
 "{0} ログをロードできません\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "インスタンス \"{1}\" の {0} ログをロードできません。"
 
@@ -1344,8 +1327,8 @@ msgid ""
 "[flavor=%(flavor)s, volume=%(volume)s, name=%(name)s, type=%(type)s, "
 "related_to=%(related_to)s, nics=%(nics)s]"
 msgstr ""
-"[フレーバー=%(flavor)s, ボリューム=%(volume)s, 名前=%(name)s, タイプ="
-"%(type)s, 関連付け先=%(related_to)s, NIC(s)=%(nics)s]"
+"[フレーバー=%(flavor)s, ボリューム=%(volume)s, 名前=%(name)s, タイプ"
+"=%(type)s, 関連付け先=%(related_to)s, NIC(s)=%(nics)s]"
 
 msgid "instance"
 msgstr "インスタンス"
diff -pruN 24.0.0-1/trove_dashboard/locale/ko_KR/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/ko_KR/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/ko_KR/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/ko_KR/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -588,9 +588,6 @@ msgstr "%(count)s개의 \"%(name)s\"이(
 msgid "Launched cluster \"%s\""
 msgstr "클러스터 \"%s\" 구동됨"
 
-msgid "Locality"
-msgstr "지역성"
-
 msgid "Log"
 msgstr "로그"
 
@@ -603,9 +600,6 @@ msgstr "로그 길이"
 msgid "Log length must be a nonnegative integer."
 msgstr "로그 길이는 음수가 아닌 정수값이어야 합니다."
 
-msgid "Log: "
-msgstr "로그:"
-
 msgid "Logs"
 msgstr "로그"
 
@@ -724,12 +718,6 @@ msgstr "Shard 개수"
 msgid "Number of instances in the cluster."
 msgstr "클러스터에 있는 인스턴스 수"
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "클러스터에 존재하는 인스턴스 수. (읽기 전용)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Shard 개수 (읽기 전용)"
-
 msgid "Old Flavor"
 msgstr "오래된 Flavor"
 
@@ -815,11 +803,6 @@ msgid ""
 "Password is only visible immediately after the root is enabled or reset."
 msgstr "패스워드는 오직 root가 리셋,enabled된 이후에 즉시 보이기 시작한다."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr "참고:</strong> 새로운 값은 기존 볼륨 크기보다 커야 합니다."
-
 msgid "Promote"
 msgstr "승격"
 
@@ -1206,6 +1189,7 @@ msgstr "부모 데이터베이스 백업
 msgid "Unable to list database instances to backup."
 msgstr "백업 데이터베이스 인스턴스를 나열할 수 없습니다."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1213,6 +1197,7 @@ msgstr ""
 "{0} 로그를 불러올 수 없습니다\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "인스턴스 \"{1}\" 에 대한 {0} 로그를 불러올 수 없습니다."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/pt_BR/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/pt_BR/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/pt_BR/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/pt_BR/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -616,9 +616,6 @@ msgstr "Disparadas %(count)s chamadas \"
 msgid "Launched cluster \"%s\""
 msgstr "Cluster iniciado \"%s\""
 
-msgid "Locality"
-msgstr "Localidade"
-
 msgid "Log"
 msgstr "Log"
 
@@ -631,9 +628,6 @@ msgstr "Tamanho do Log"
 msgid "Log length must be a nonnegative integer."
 msgstr "Tamanho do log deve ser um número inteiro não negativo."
 
-msgid "Log: "
-msgstr "Log:"
-
 msgid "Logs"
 msgstr "Logs"
 
@@ -752,12 +746,6 @@ msgstr "Numero de Shards"
 msgid "Number of instances in the cluster."
 msgstr "Número de Instâncias no cluster."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Número de instâncias no cluster. (Somente leitura)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Numero de Shards. (Somente leitura)"
-
 msgid "Old Flavor"
 msgstr "Flavor antigo"
 
@@ -851,13 +839,6 @@ msgstr ""
 "A senha é apenas visível imediatamente após o root ser habilitado ou "
 "redefinido."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Por favor, observe:</strong> O novo valor deve ser maior do que o tamanho do "
-"volume existente."
-
 msgid "Promote"
 msgstr "Promover"
 
@@ -1262,6 +1243,7 @@ msgstr "Não foi possível listar os bac
 msgid "Unable to list database instances to backup."
 msgstr "Não foi possível listar as instâncias de banco de dados para backup."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1269,6 +1251,7 @@ msgstr ""
 "Não é possível carregar {0} log\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "Não é possível carregar {0} log para a instância \"{1}\"."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/ru/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/ru/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/ru/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/ru/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -3,21 +3,23 @@
 # Maxim Bozhenko <mbozhenko@gmail.com>, 2016. #zanata
 # Vladimir Sokolov <vsokolov@hystax.com>, 2016. #zanata
 # Yulia Ryndenkova <yryndenkova@hystax.com>, 2016. #zanata
+# Dmitriy Chubinidze <dcu995@gmail.com>, 2025. #zanata
+# Ivan Anfimov <lazekteam@gmail.com>, 2025. #zanata
 msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2016-10-12 02:47+0000\n"
-"Last-Translator: Maxim Bozhenko <mbozhenko@gmail.com>\n"
+"PO-Revision-Date: 2025-09-08 11:42+0000\n"
+"Last-Translator: Ivan Anfimov <lazekteam@gmail.com>\n"
 "Language-Team: Russian\n"
 "Language: ru\n"
 "X-Generator: Zanata 4.3.3\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
 
 #, python-format
 msgid "%(name)s | %(RAM)s RAM"
@@ -25,36 +27,46 @@ msgstr "%(name)s | %(RAM)s RAM"
 
 #, python-format
 msgid "%(name)s | %(RAM)s RAM | %(instances)s instances"
-msgstr "%(name)s | %(RAM)s ОЗУ | Инстансов - %(instances)s "
+msgstr "%(name)s | %(RAM)s RAM | Инстансов %(instances)s"
 
 msgid "-"
 msgstr "-"
 
 msgid ""
+"<strong>Please note:</strong> It may be necessary to reboot the database "
+"instance for this new configuration group to take effect."
+msgstr ""
+"<strong>Обратите внимание:</strong> может потребоваться перезагрузка "
+"инстанса базы данных, чтобы эта новая группа конфигурации вступила в силу."
+
+msgid ""
 "<strong>Please note:</strong> The value specified in the Volume Size field "
 "should be greater than 0, however, some configurations do not support "
 "specifying volume size. If specifying the volume size results in an error "
 "stating volume support is not enabled, enter 0."
 msgstr ""
-"<strong>Обратите внимание:</strong> Значение указываемое в поле Размер диска "
-"должно быть больше 0, однако некоторые конфигурации не поддерживают указание "
-"размера диска. Если при указание размера диска возникает ошибка говорящая о "
-"том что поддержка дисков не включена укажите 0."
+"<strong>Обратите внимание:</strong> значение, указываемое в поле \"Размер "
+"диска\" должно быть больше 0, однако, некоторые конфигурации не поддерживают "
+"указание размера диска. Если при указании размера диска возникает ошибка, "
+"говорящая о том, что поддержка дисков не включена, укажите 0."
 
 msgid "A backup must be selected!"
 msgstr "Нужно выбрать резервную копию!"
 
 msgid "A master instance must be selected!"
-msgstr "Должна быть выбран основной инстанс!"
+msgstr "Необходимо выбрать основной инстанс!"
 
 msgid "A new name or new password or new host must be specified."
 msgstr "Новое имя, новый пароль и новый хост должны быть заданы."
 
 msgid "Access Revoked to"
 msgid_plural "Access Revoked to"
-msgstr[0] "Отменен доступ к "
-msgstr[1] "Отменены доступы к "
-msgstr[2] "Отменены доступы к "
+msgstr[0] "Отозван доступ к"
+msgstr[1] "Отозван доступ к"
+msgstr[2] "Отозван доступ к"
+
+msgid "Access defines how the database service is exposed."
+msgstr "Доступ определяет, как используется служба базы данных."
 
 msgid "Accessible"
 msgstr "Доступно"
@@ -75,11 +87,21 @@ msgstr "Добавить парамет
 msgid "Advanced"
 msgstr "Дополнительно"
 
+msgid ""
+"Allow the user to connect from this host only. If not provided this user "
+"will be allowed to connect from anywhere."
+msgstr ""
+"Разрешить пользователю подключаться только с этого хоста. Если не указано, "
+"этому пользователю будет разрешено подключаться с любого адреса."
+
+msgid "Allowed CIDRs"
+msgstr "Разрешенные CIDR"
+
 msgid "Allowed Host"
 msgstr "Разрешенный хост"
 
 msgid "Allowed Host (optional)"
-msgstr "Разрешенный узел (необязательно)"
+msgstr "Разрешенный хост (опционально)"
 
 msgid "Any Availability Zone"
 msgstr "Любая зона доступности"
@@ -88,7 +110,7 @@ msgid "Applicable only if the volume siz
 msgstr "Поддерживается только если указан размер диска."
 
 msgid "Applied changes to server"
-msgstr "Изменения применены"
+msgstr "Изменения применены на сервер"
 
 msgid "Apply Changes"
 msgstr "Применить изменения"
@@ -112,21 +134,24 @@ msgstr "Зона доступности"
 msgid "Available networks"
 msgstr "Доступные сети"
 
+msgid "Backend"
+msgstr "Бэкенд"
+
 msgctxt "Current status of a Database Instance"
 msgid "Backup"
 msgstr "Резервное копирование"
 
 msgid "Backup Database"
-msgstr "Резервная копия БД"
+msgstr "Создать резервную копию базы данных"
 
 msgid "Backup Details"
-msgstr "Сведения о резервной копии"
+msgstr "Подробности резервной копии"
 
 msgid "Backup Details: {{ backup.name }}"
-msgstr "Детали резервной копии: {{ backup.name }}"
+msgstr "Подробности резервной копии: {{ backup.name }}"
 
 msgid "Backup Duration"
-msgstr "Продолжительность резервной копии"
+msgstr "Продолжительность резервного копирования"
 
 msgid "Backup File"
 msgstr "Файл резервной копии"
@@ -140,6 +165,21 @@ msgstr "Имя резервной коп
 msgid "Backup Overview"
 msgstr "Обзор резервной копии"
 
+msgid "Backup Strategies"
+msgstr "Стратегии резервного копирования"
+
+msgid "Backup Strategy"
+msgstr "Стратегия резервного копирования"
+
+msgid "Backup Strategy Deleted"
+msgid_plural "Backup Strategies Deleted"
+msgstr[0] "Стратегия резервного копирования удалена"
+msgstr[1] "Стратегии резервного копирования удалены"
+msgstr[2] "Стратегии резервного копирования удалены"
+
+msgid "Backup strategy created"
+msgstr "Создана стратегия резервного копирования"
+
 msgid "Backups"
 msgstr "Резервные копии"
 
@@ -155,24 +195,49 @@ msgctxt "Current status of a Database In
 msgid "Building"
 msgstr "Создание"
 
+msgid ""
+"CIDRs is a comma-separated list of IPv4, IPv6 or mix of both CIDRs that "
+"restrict access to the database service. 0.0.0.0/0 is used by default if "
+"this parameter is not provided. E.g.: 0.0.0.0/0,202.78.240.0/24"
+msgstr ""
+"CIDR — это разделенный запятыми список IPv4, IPv6 или смесь обоих CIDR, "
+"которые ограничивают доступ к службе базы данных. Если этот параметр не "
+"указан, по умолчанию используется 0.0.0.0/0. Например: "
+"0.0.0.0/0,202.78.240.0/24"
+
 msgid "Cancel"
 msgstr "Отмена"
 
 #, python-format
 msgid "Cannot disable root access: %s"
-msgstr "Невозможно отключить доступ к root: %s"
+msgstr "Невозможно отключить полный доступ: %s"
 
 msgid "Cannot grow cluster.  No instances specified."
-msgstr "Не могу увеличить кластер. Инстансы не заданы."
+msgstr "Невозможно увеличить кластер. Не указаны инстансы."
 
 msgid "Character Set"
 msgstr "Кодировка"
 
 msgid "Choose a new instance flavor."
-msgstr "Выберите новый тип для инстанса."
+msgstr "Выберите новый шаблон конфигурации для инстанса."
 
 msgid "Choose initial state."
-msgstr "Выберите первоначальное наполнение"
+msgstr "Выберите начальное состояние."
+
+msgid ""
+"Choose network from Available networks to Selected networks by push button "
+"or drag and drop, you may change NIC order by drag and drop as well. "
+msgstr ""
+"Выберите сеть из списка \"Доступные сети\" или \"Выбранные сети\" с помощью "
+"кнопки или перетаскивания. Вы также можете изменить порядок сетевых карт с "
+"помощью перетаскивания."
+
+msgid ""
+"Classless Inter-Domain Routing (e.g. 192.168.0.0/24, or 2001:db8::/128). Can "
+"enter multiple values separatingby a comma"
+msgstr ""
+"Бесклассовая междоменная маршрутизация (например, 192.168.0.0/24 или 2001:"
+"db8::/128). Можно ввести несколько значений, разделяя их запятыми"
 
 msgid "Close"
 msgstr "Закрыть"
@@ -187,23 +252,26 @@ msgid "Clusters"
 msgstr "Кластеры"
 
 msgid "Collation"
-msgstr "Параметры сортировки"
+msgstr "Сортировка"
 
 msgid "Comma separated list of databases to create"
 msgstr "Список баз данных для создания разделенный запятыми"
 
+msgid "Comma-separated CIDRs to connect through."
+msgstr "CIDR-адреса для подключения, разделенные запятыми."
+
 msgctxt "Current status of a Database Backup"
 msgid "Completed"
 msgstr "Завершено"
 
 msgid "Configuration Defaults"
-msgstr "Установки по умолчанию"
+msgstr "Конфигурация по умолчанию"
 
 msgid "Configuration Group"
 msgstr "Группа конфигурации"
 
 msgid "Configuration Group Details: {{configuration.name}}"
-msgstr "Детали группы конфигурации: {{configuration.name}}"
+msgstr "Подробности группы конфигурации: {{configuration.name}}"
 
 msgid "Configuration Group Instances"
 msgstr "Инстансы группы конфигурации"
@@ -217,18 +285,27 @@ msgstr "Обзор группы конф
 msgid "Configuration Group Values"
 msgstr "Значения группы конфигурации"
 
+msgid "Configuration Group attached to instance."
+msgstr "Группа конфигурации, привязанная к инстансу."
+
+msgid "Configuration Group attached to instances."
+msgstr "Группа конфигурации, привязанная к инстансам."
+
 msgid "Configuration Groups"
-msgstr "Группы конфигураций"
+msgstr "Группы конфигурации"
+
+msgid "Configurations"
+msgstr "Конфигурации"
 
 msgid ""
 "Confirm the current replica is to be promoted as the new replica source."
 msgstr "Подтвердите назначение текущей реплики источником реплик."
 
 msgid "Connection Examples"
-msgstr "Примеры соединений"
+msgstr "Примеры подключения"
 
 msgid "Connection Information"
-msgstr "Параметры соединения"
+msgstr "Информация о подключении"
 
 msgid "Container"
 msgstr "Контейнер"
@@ -236,6 +313,9 @@ msgstr "Контейнер"
 msgid "Create Backup"
 msgstr "Создать резервную копию"
 
+msgid "Create Backup Strategy"
+msgstr "Создать стратегию резервного копирования"
+
 msgid "Create Configuration Group"
 msgstr "Создать группу конфигурации"
 
@@ -245,6 +325,13 @@ msgstr "Создать базу данн
 msgid "Create User"
 msgstr "Создать пользователя"
 
+msgid ""
+"Create an optional initial user. This user will have access to all databases "
+"you create."
+msgstr ""
+"Создайте начального пользователя (опционально). Этот пользователь будет "
+"иметь доступ ко всем созданным вами базам данных."
+
 msgid "Created"
 msgstr "Создано"
 
@@ -253,7 +340,7 @@ msgstr "Группа конфигура
 
 #, python-format
 msgid "Created database \"%s\"."
-msgstr "Создана БД \"%s\"."
+msgstr "Создана база данных \"%s\"."
 
 #, python-format
 msgid "Created user \"%s\"."
@@ -272,22 +359,25 @@ msgid "Current Task"
 msgstr "Текущая задача"
 
 msgid "DATABASE"
-msgstr "DATABASE"
+msgstr "БАЗА ДАННЫХ"
 
 msgid "Database"
 msgstr "База данных"
 
 msgid "Database Access"
-msgstr "Доступ к БД"
+msgstr "Доступ к базе данных"
+
+msgid "Database Access for: {{ user_name }}@{{user_host}}"
+msgstr "Доступ к базе данных для: {{ user_name }}@{{user_host}}"
 
 msgid "Database Backups"
-msgstr "Резервные копии БД"
+msgstr "Резервные копии базы данных"
 
 msgid "Database Info"
-msgstr "Информация БД"
+msgstr "Информация о базе данных"
 
 msgid "Database Instance"
-msgstr "Инстанс БД"
+msgstr "Инстанс базы данных"
 
 msgid "Database Name"
 msgstr "Имя базы данных"
@@ -295,6 +385,12 @@ msgstr "Имя базы данных"
 msgid "Database Port"
 msgstr "Порт базы данных"
 
+msgid "Database Service stopped"
+msgid_plural "Database Services stopped"
+msgstr[0] "Служба базы данных остановлена"
+msgstr[1] "Службы базы данных остановлены"
+msgstr[2] "Службы базы данных остановлены"
+
 msgid "Databases"
 msgstr "Базы данных"
 
@@ -305,7 +401,7 @@ msgid "Datastore Version"
 msgstr "Версия хранилища данных"
 
 msgid "Defaults"
-msgstr "Установки по умолчанию"
+msgstr "Параметры по умолчанию"
 
 msgid "Delete Backup"
 msgid_plural "Delete Backups"
@@ -313,12 +409,24 @@ msgstr[0] "Удалить резервн
 msgstr[1] "Удалить резервные копии"
 msgstr[2] "Удалить резервные копии"
 
+msgid "Delete Backup Strategy"
+msgid_plural "Delete Backup Strategies"
+msgstr[0] "Удалить стратегию резервного копирования"
+msgstr[1] "Удалить стратегии резервного копирования"
+msgstr[2] "Удалить стратегии резервного копирования"
+
 msgid "Delete Cluster"
 msgid_plural "Delete Clusters"
 msgstr[0] "Удалить кластер"
 msgstr[1] "Удалить кластеры"
 msgstr[2] "Удалить кластеры"
 
+msgid "Delete Configuration Group"
+msgid_plural "Delete Configuration Groups"
+msgstr[0] "Удалить группу конфигурации"
+msgstr[1] "Удалить группы конфигурации"
+msgstr[2] "Удалить группы конфигурации"
+
 msgid "Delete Database"
 msgid_plural "Delete Databases"
 msgstr[0] "Удалить базу данных"
@@ -335,6 +443,12 @@ msgstr[0] "Удалить инстанс
 msgstr[1] "Удалить инстансы"
 msgstr[2] "Удалить инстансы"
 
+msgid "Delete Parameter"
+msgid_plural "Delete Parameters"
+msgstr[0] "Удалить параметр"
+msgstr[1] "Удалить параметры"
+msgstr[2] "Удалить параметры"
+
 msgid "Delete User"
 msgid_plural "Delete Users"
 msgstr[0] "Удалить пользователя"
@@ -343,9 +457,15 @@ msgstr[2] "Удалить пользов
 
 msgid "Deleted Backup"
 msgid_plural "Deleted Backups"
-msgstr[0] "Удаленная резервная копия"
-msgstr[1] "Удаленные резервные копии"
-msgstr[2] "Удаленные резервные копии"
+msgstr[0] "Резервная копия удалена"
+msgstr[1] "Резервные копии удалены"
+msgstr[2] "Резервные копии удалены"
+
+msgid "Deleted Configuration Group"
+msgid_plural "Deleted Configuration Groups"
+msgstr[0] "Группа конфигурации удалена"
+msgstr[1] "Группы конфигурации удалены"
+msgstr[2] "Группы конфигурации удалены"
 
 msgid "Deleted Database"
 msgid_plural "Deleted Databases"
@@ -353,14 +473,20 @@ msgstr[0] "База данных уда
 msgstr[1] "Базы данных удалены"
 msgstr[2] "Базы данных удалены"
 
+msgid "Deleted Parameter"
+msgid_plural "Deleted Parameters"
+msgstr[0] "Параметр удален"
+msgstr[1] "Параметры удалены"
+msgstr[2] "Параметры удалены"
+
 msgid "Deleted User"
 msgid_plural "Deleted Users"
-msgstr[0] "Удаленный пользователь"
-msgstr[1] "Удаленные пользователи"
-msgstr[2] "Удаленные пользователи"
+msgstr[0] "Пользователь удален"
+msgstr[1] "Пользователи удалены"
+msgstr[2] "Пользователи удалены"
 
 msgid "Deleted cluster is not recoverable."
-msgstr "Удаленный кластер не подлежит восстановлению"
+msgstr "Удаленный кластер не подлежит восстановлению."
 
 msgid "Deleted instances are not recoverable."
 msgstr "Удаленные инстансы нельзя восстановить."
@@ -371,8 +497,8 @@ msgstr "Описание"
 msgid "Detach Configuration Group"
 msgid_plural "Detach Configuration Groups"
 msgstr[0] "Отключить группу конфигурации"
-msgstr[1] "Отключить группы конфигураций"
-msgstr[2] "Отключить группы конфигураций"
+msgstr[1] "Отключить группы конфигурации"
+msgstr[2] "Отключить группы конфигурации"
 
 msgid "Detach Replica"
 msgid_plural "Detach Replicas"
@@ -382,42 +508,42 @@ msgstr[2] "Отключить репли
 
 msgid "Detached Configuration Group"
 msgid_plural "Detached Configuration Groups"
-msgstr[0] "Отключенная группа конфигурации"
-msgstr[1] "Отключенные группы конфигураций"
-msgstr[2] "Отключенные группы конфигураций"
+msgstr[0] "Группа конфигурации отключена"
+msgstr[1] "Группы конфигурации отключены"
+msgstr[2] "Группы конфигурации отключены"
 
 msgid "Details"
 msgstr "Подробности"
 
 msgid "Disable Log"
 msgid_plural "Disable Logs"
-msgstr[0] "Выключить лог"
-msgstr[1] "Выключить логи"
-msgstr[2] "Выключить логи"
+msgstr[0] "Выключить журнал"
+msgstr[1] "Выключить журналы"
+msgstr[2] "Выключить журналы"
 
 msgid "Disable Root"
-msgstr "Отключить root"
+msgstr "Отключить полный доступ"
 
 msgid "Disabled Log"
 msgid_plural "Disabled Logs"
-msgstr[0] "Выключенный лог"
-msgstr[1] "Выключенные логи"
-msgstr[2] "Выключенные логи"
+msgstr[0] "Журнал отключен"
+msgstr[1] "Журналы отключены"
+msgstr[2] "Журналы отключены"
 
 msgid "Discard Changes"
 msgstr "Отменить изменения"
 
 msgid "Discard Log"
 msgid_plural "Discard Logs"
-msgstr[0] "Удалить лог"
-msgstr[1] "Удалить логи"
-msgstr[2] "Удалить логи"
+msgstr[0] "Удалить журнал"
+msgstr[1] "Удалить журналы"
+msgstr[2] "Удалить журналы"
 
 msgid "Discarded Log"
 msgid_plural "Discarded Logs"
-msgstr[0] "Удаленный лог"
-msgstr[1] "Удаленные логи"
-msgstr[2] "Удаленные логи"
+msgstr[0] "Журнал удален"
+msgstr[1] "Журналы удалены"
+msgstr[2] "Журналы удалены"
 
 msgid "Download"
 msgstr "Скачать"
@@ -426,34 +552,34 @@ msgid "Download Backup"
 msgstr "Скачать резервную копию"
 
 msgid "Edit User"
-msgstr "Редактировать пользователя"
+msgstr "Изменить пользователя"
 
 msgid "Eject Replica Source"
 msgid_plural "Eject Replica Sources"
-msgstr[0] "Отключить источник реплик"
-msgstr[1] "Отключить источники реплик"
-msgstr[2] "Отключить источники реплик"
+msgstr[0] "Отключить источник реплики"
+msgstr[1] "Отключить источники реплики"
+msgstr[2] "Отключить источники реплики"
 
 msgid "Ejected Replica Source"
 msgid_plural "Ejected Replica Sources"
-msgstr[0] "Отключенный источник реплик"
-msgstr[1] "Отключенные источники реплик"
-msgstr[2] "Отключенные источники реплик"
+msgstr[0] "Источник реплики отключен"
+msgstr[1] "Источники реплики отключены"
+msgstr[2] "Источники реплики отключены"
 
 msgid "Enable Log"
 msgid_plural "Enable Logs"
-msgstr[0] "Включить лог"
-msgstr[1] "Включить логи"
-msgstr[2] "Включить логи"
+msgstr[0] "Включить журнал"
+msgstr[1] "Включить журналы"
+msgstr[2] "Включить журналы"
 
 msgid "Enable Root"
-msgstr "Разрешить пользователя root"
+msgstr "Включить полный доступ"
 
 msgid "Enabled Log"
 msgid_plural "Enabled Logs"
-msgstr[0] "Включенный лог"
-msgstr[1] "Включенные логи"
-msgstr[2] "Включенные логи"
+msgstr[0] "Журнал включен"
+msgstr[1] "Журналы включены"
+msgstr[2] "Журналы включены"
 
 msgctxt "Current status of a Database Instance"
 msgid "Error"
@@ -462,39 +588,45 @@ msgstr "Ошибка"
 msgid "Error applying changes"
 msgstr "Ошибка при применении изменений"
 
+msgid "Error creating backup strategy."
+msgstr "Ошибка создания стратегии резервного копирования."
+
 msgid "Error creating database backup."
-msgstr "Ошибка создания резервной копии БД."
+msgstr "Ошибка создания резервной копии базы данных."
 
 msgid "Error deleting database on instance."
-msgstr "Ошибка удаления БД на  инстансе."
+msgstr "Ошибка удаления базы данных в инстансе."
 
 #, python-format
 msgid "Error downloading log file: %s"
-msgstr "Ошибка загрузки файла лога: %s"
+msgstr "Ошибка загрузки файла журнала: %s"
+
+msgid "Error getting backup strategies list."
+msgstr "Ошибка получения списка стратегий резервного копирования."
 
 msgid "Error getting configuration group list."
 msgstr "Ошибка получения списка групп конфигурации."
 
 msgid "Error getting database backup list."
-msgstr "Ошибка получения списка резервных копий БД."
+msgstr "Ошибка получения списка резервных копий базы данных."
 
 #, python-format
 msgid "Error resetting parameters: %s"
-msgstr "Ошибка при очистке параметров: %s"
+msgstr "Ошибка при сбросе параметров: %s"
 
 msgctxt "Current status of a Database Backup"
 msgid "Failed"
-msgstr "Произошла ошибка"
+msgstr "Ошибка"
 
 msgctxt "Current status of a Database Instance"
 msgid "Failed"
-msgstr "Произошла ошибка"
+msgstr "Не удалось"
 
 msgid "Fault"
 msgstr "Ошибка"
 
 msgid "Flavor"
-msgstr "Тип инстанса"
+msgstr "Шаблон конфигурации"
 
 msgid "GB"
 msgstr "ГБ"
@@ -504,15 +636,15 @@ msgstr "Выполнить"
 
 msgid "Grant Access"
 msgid_plural "Grant Access"
-msgstr[0] "Дать доступ"
-msgstr[1] "Дать доступы"
-msgstr[2] "Дать доступы"
+msgstr[0] "Предоставить доступ"
+msgstr[1] "Предоставить доступ"
+msgstr[2] "Предоставить доступ"
 
 msgid "Granted Access to"
 msgid_plural "Granted Access to"
-msgstr[0] "Дан доступ к "
-msgstr[1] "Даны доступы к "
-msgstr[2] "Даны доступы к "
+msgstr[0] "Предоставлен доступ к"
+msgstr[1] "Предоставлен доступ к"
+msgstr[2] "Предоставлен доступ к"
 
 msgid "Grow Cluster"
 msgstr "Увеличить кластер"
@@ -521,22 +653,26 @@ msgid "Grow Cluster: {{cluster_name}}"
 msgstr "Увеличить кластер: {{cluster_name}}"
 
 msgid "Has Root Ever Been Enabled"
-msgstr "Был ли когда-то включен root"
+msgstr "Был ли когда-то включен полный доступ"
+
+msgctxt "Current status of a Database Instance"
+msgid "Healthy"
+msgstr "Здоровый"
 
 msgid "Host"
 msgstr "Хост"
 
 msgid "Host or IP that the user is allowed to connect through."
-msgstr "Хост или IP через который пользователю разрешено подключиться."
+msgstr "Хост или IP, через который пользователю разрешено подключаться."
 
 msgid "ID"
 msgstr "ID"
 
 msgid "Incremental"
-msgstr "Инкрементное"
+msgstr "Инкрементальный"
 
 msgid "Incremental Backup"
-msgstr "Инкрементное резервное копирование"
+msgstr "Инкрементальное резервное копирование"
 
 msgid "Info"
 msgstr "Информация"
@@ -551,14 +687,22 @@ msgid "Initial Databases"
 msgstr "Начальные базы данных"
 
 msgid "Initial Volume Size"
-msgstr "Изначальный размер диска"
+msgstr "Начальный размер диска"
 
 msgid "Initial admin user to add"
-msgstr "Начальный пользователь-администратор для добавления"
+msgstr ""
+"Начальный администратор, который будет добавлен при создании базы данных"
 
 msgid "Initialize Databases"
 msgstr "Инициализировать базы данных"
 
+#, python-format
+msgid "Instance \"%s\" successfully updated."
+msgstr "Инстанс \"%s\" успешно обновлен."
+
+msgid "Instance ID"
+msgstr "ID инстанса"
+
 msgid "Instance Name"
 msgstr "Имя инстанса"
 
@@ -568,6 +712,9 @@ msgstr "Тип инстанса"
 msgid "Instances"
 msgstr "Инстансы"
 
+msgid "Is Public"
+msgstr "Публичный"
+
 msgid "Is a Replica Of"
 msgstr "Является репликой"
 
@@ -578,7 +725,7 @@ msgid "Launch Cluster"
 msgstr "Запустить кластер"
 
 msgid "Launch Database"
-msgstr "Запустить БД"
+msgstr "Запустить базу данных"
 
 msgid "Launch Instance"
 msgstr "Запустить инстанс"
@@ -588,41 +735,50 @@ msgstr "Запустить инстан
 
 #, python-format
 msgid "Launched %(count)s named \"%(name)s\"."
-msgstr "Запущено %(count)s названных \"%(name)s\"."
+msgstr "Запущен %(count)s с именем \"%(name)s\"."
 
 #, python-format
 msgid "Launched cluster \"%s\""
 msgstr "Запущен кластер %s"
 
-msgid "Locality"
-msgstr "Окрестность"
+msgid "Location Policy"
+msgstr "Политика расположения"
 
 msgid "Log"
-msgstr "Лог"
+msgstr "Журнал"
 
 msgid "Log Contents"
-msgstr "Содержимое лога"
+msgstr "Содержимое журнала"
 
 msgid "Log Length"
-msgstr "Длина лога"
+msgstr "Длина журнала"
 
 msgid "Log length must be a nonnegative integer."
 msgstr "Длина журнала должна быть неотрицательным целым числом. "
 
-msgid "Log: "
-msgstr "Лог:"
+msgid "Log:"
+msgstr "Журнал:"
 
 msgid "Logs"
-msgstr "Логи"
+msgstr "Журналы"
 
 msgid "Manage Access"
 msgstr "Управление доступом"
 
 msgid "Manage Root"
-msgstr "Управление root"
+msgstr "Управление полным доступом"
 
 msgid "Manage Root Access"
-msgstr "Управление правами root"
+msgstr "Управление полным доступом"
+
+msgid ""
+"Manage parameters of the configuration group. If the configuration group is "
+"attached with database instance, the change is applied to the instance "
+"synchronously."
+msgstr ""
+"Управление параметрами группы конфигурации. Если группа конфигурации "
+"подключена к инстансу базы данных, изменение применяется к инстансу "
+"синхронно."
 
 msgid "Management Console"
 msgstr "Консоль управления"
@@ -633,6 +789,15 @@ msgstr "Имя основного инс
 msgid "Message"
 msgstr "Сообщение"
 
+msgid ""
+"Move networks from 'Available Networks' to 'Selected Networks' by clicking "
+"the button, or dragging and dropping. You can change the NIC order by "
+"dragging and dropping as well."
+msgstr ""
+"Переместите сети из \"Доступные сети\" в \"Выбранные сети\", нажав кнопку "
+"или перетащив их. Вы также можете изменить порядок сетевых карт, перетащив "
+"их."
+
 msgid "Name"
 msgstr "Имя"
 
@@ -640,20 +805,23 @@ msgid "Network"
 msgstr "Сеть"
 
 msgid "Network attached to instance."
-msgstr "Сеть подключенная к инстансу."
+msgstr "Сеть, подключенная к инстансу."
 
 msgid "Networking"
 msgstr "Сеть"
 
+msgid "Networking Information"
+msgstr "Сетевая информация"
+
 msgid "Networks"
 msgstr "Сети"
 
 msgctxt "Current status of a Database Backup"
 msgid "New"
-msgstr "Новая копия"
+msgstr "Новая"
 
 msgid "New Flavor"
-msgstr "Новый тип инстанса"
+msgstr "Новый шаблон конфигурации"
 
 msgid "New Host"
 msgstr "Новый хост"
@@ -665,7 +833,7 @@ msgid "New Password"
 msgstr "Новый пароль"
 
 msgid "New Size (GB)"
-msgstr "Новый размер (Гб)"
+msgstr "Новый размер (ГБ)"
 
 msgid "New password for cluster access."
 msgstr "Новый пароль для доступа к кластеру."
@@ -674,19 +842,19 @@ msgid "New size for volume must be great
 msgstr "Новый размер диска должен быть больше текущего размера."
 
 msgid "No availability zones found"
-msgstr "Не найдены зоны доступности."
+msgstr "Не найдены зоны доступности"
 
 msgid "No backups available"
-msgstr "Нет доступных резервных копий"
+msgstr "Резервные копии отсутствуют"
 
 msgid "No configuration groups available"
-msgstr "Нет доступных групп конфигураций"
+msgstr "Нет доступных групп конфигурации"
 
 msgid "No configurations available"
 msgstr "Нет доступных конфигураций"
 
 msgid "No flavors available"
-msgstr "Нет доступных типов инстанса"
+msgstr "Нет доступных шаблонов конфигураций"
 
 msgid "No instances available"
 msgstr "Нет доступных инстансов"
@@ -710,8 +878,8 @@ msgid ""
 "Note: Enable root access on an instance.  If the root user is already "
 "enabled then a new password is generated."
 msgstr ""
-"Замечание: Разрешите root доступ к инстансу. Если root доступ уже разрешен, "
-"тогда будет сгенерирован новый пароль."
+"Примечание: включите полный доступ к инстансу. Если полный доступ уже "
+"включен, тогда будет сгенерирован новый пароль."
 
 msgid "Number of Instances"
 msgstr "Количество инстансов"
@@ -719,77 +887,80 @@ msgstr "Количество инста
 msgid "Number of Shards"
 msgstr "Количество шардов"
 
+msgid "Number of instances in the cluster (read only)."
+msgstr "Количество инстансов в кластере (только чтение)."
+
 msgid "Number of instances in the cluster."
 msgstr "Количество инстансов в кластере."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Количество инстансов в кластере. (Только чтение)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Количество шардов. (Только чтение)"
+msgid "Number of shards (read only)."
+msgstr "Количество шардов (только чтение)."
 
 msgid "Old Flavor"
-msgstr "Старый тип инстанса"
+msgstr "Старый шаблон конфигурации"
+
+msgid "Operating Status"
+msgstr "Рабочий статус"
 
 msgid "Optional Backup Description"
 msgstr "Опциональное описание резервной копии"
 
 msgid "Optional character set for the database."
-msgstr "Опциональная кодировка для БД"
+msgstr "Опциональная установка кодировки для базы данных."
 
 msgid "Optional collation type for the database."
-msgstr "Опциональные параметры сортировки для БД"
+msgstr "Опциональный тип сортировки для базы данных."
 
 msgid "Optional comma separated list of databases user has access to."
 msgstr ""
-"Опциональный список БД, разделенный запятыми, к которым пользователь имеет "
-"доступ."
+"Опциональный список баз данных, разделенный запятыми, к которым пользователь "
+"имеет доступ."
 
 msgid "Optional datastore specific type of the instance."
-msgstr "Опциональный тип инстанса для хранилища данных."
+msgstr "Опциональный тип конкретного хранилища данных для инстанса."
 
 msgid ""
 "Optional datastore specific value that defines the relationship from one "
 "instance in the cluster to another."
 msgstr ""
-"Опциональное значение для хранилища данных которое определяет отношение "
-"между инстансами в кластере"
+"Опциональное значение для конкретного хранилища данных, определяющее связь "
+"одного инстанса в кластере с другим."
 
 msgid "Optional host of user."
-msgstr "Опциональный хост пользователя"
+msgstr "Опциональный хост пользователя."
 
 msgid "Optional name of the instance."
 msgstr "Опциональное имя инстанса."
 
 msgid "Optional parent backup"
-msgstr "Необязательная материнская резервная копия"
+msgstr "Опциональная родительская резервная копия"
 
 msgid ""
 "Optionally choose to create this database using a previous backup, or as a "
 "replica of another database instance."
 msgstr ""
-"Дополнительно можно выбрать создание этой базы данных из резервной копии или "
-"в качестве реплики другого экземпляра БД."
+"Опционально можно выбрать создание этой базы данных с использованием "
+"предыдущей резервной копии или как реплики другого инстанса базы данных."
 
 msgid "Optionally provide a character set and collation for the database."
-msgstr "Опционально укажите кодировку и параметры сортировки для БД."
+msgstr "Опционально укажите кодировку и сортировку для базы данных."
 
 msgid "Optionally provide a comma separated list of databases to create:"
 msgstr ""
-"Опционально введите список баз данных для создания, разделенный запятыми: "
+"Опционально укажите список баз данных, разделенных запятыми, для создания:"
 
 msgid ""
 "Optionally provide the host of the user and a list of databases the user is "
 "granted access to."
 msgstr ""
-"Опционально предоставьте хост для пользователя и список БД к которым "
+"Опционально укажите хост пользователя и список баз данных, к которым "
 "пользователь имеет доступ."
 
 msgid "Overview"
 msgstr "Обзор"
 
 msgid "PASSWORD"
-msgstr "PASSWORD"
+msgstr "ПАРОЛЬ"
 
 msgid "Parameter"
 msgstr "Параметр"
@@ -798,7 +969,7 @@ msgid "Parameters"
 msgstr "Параметры"
 
 msgid "Parent Backup"
-msgstr "Материнская резервная копия"
+msgstr "Родительская резервная копия"
 
 msgid "Password"
 msgstr "Пароль"
@@ -810,37 +981,41 @@ msgid "Password for root user must be sp
 msgstr "Должен быть указан пароль для пользователя root."
 
 msgid "Password for root user."
-msgstr "Пароль пользователя root"
+msgstr "Пароль для пользователя root."
 
 msgid ""
 "Password is only visible immediately after the root is enabled or reset."
-msgstr "Пароль видим сразу только  после разрешения или сброса root."
+msgstr ""
+"Пароль сразу становится видимым только после включения или сброса полного "
+"доступа."
 
 msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
+"Please note: The new value must be greater than the existing volume size."
 msgstr ""
-"Пожалуйста, обратите внимание: </strong> Новое значение должно быть больше "
-"чем текущего размер диска."
+"Обратите внимание: новое значение должно быть больше существующего размера "
+"диска."
+
+msgid "Project"
+msgstr "Проект"
 
 msgid "Promote"
-msgstr "Повысить"
+msgstr "Продвинуть"
 
 msgid "Promote to Replica Source"
-msgstr "Сделать источником реплик"
+msgstr "Назначить источником реплики"
 
 #, python-format
 msgid "Promoted replica \"%s\" as the new replica source."
-msgstr "Реплика \"%s\" теперь источник реплик."
+msgstr "Реплика \"%s\" назначена как новый источник реплики."
 
 msgid "Property"
 msgstr "Свойство"
 
 msgid "Publish Log"
 msgid_plural "Publish Logs"
-msgstr[0] "Опубликовать лог"
-msgstr[1] "Опубликовать логи"
-msgstr[2] "Опубликовать логи"
+msgstr[0] "Опубликовать журнал"
+msgstr[1] "Опубликовать журналы"
+msgstr[2] "Опубликовать журналы"
 
 msgid "Publishable (bytes)"
 msgstr "Может быть опубликовано (байт)"
@@ -850,9 +1025,9 @@ msgstr "Опубликовано (бай
 
 msgid "Published Log"
 msgid_plural "Published Logs"
-msgstr[0] "Опубликованный лог"
-msgstr[1] "Опубликованные логи"
-msgstr[2] "Опубликованные логи"
+msgstr[0] "Журнал опубликован"
+msgstr[1] "Журналы опубликованы"
+msgstr[2] "Журналы опубликованы"
 
 msgid "RAM"
 msgstr "RAM"
@@ -872,12 +1047,12 @@ msgstr[2] "Удалить инстанс
 
 msgid "Removed Instance"
 msgid_plural "Removed Instances"
-msgstr[0] "Удаленный инстанс"
-msgstr[1] "Удаленные инстансы"
-msgstr[2] "Удаленные инстансы"
+msgstr[0] "Инстанс удален"
+msgstr[1] "Инстансы удалены"
+msgstr[2] "Инстансы удалены"
 
 msgid "Removed instances from cluster."
-msgstr "Удаленные инстансы из кластера"
+msgstr "Инстансы удалены из кластера."
 
 msgid "Replica Count"
 msgstr "Количество реплик"
@@ -888,6 +1063,10 @@ msgstr[0] "Реплика отключе
 msgstr[1] "Реплики отключены"
 msgstr[2] "Реплики отключены"
 
+#, python-format
+msgid "Replica of %s"
+msgstr "Реплика %s"
+
 msgid "Replicas"
 msgstr "Реплики"
 
@@ -897,14 +1076,17 @@ msgstr "Реплицировать с и
 msgid "Replication"
 msgstr "Репликация"
 
+msgid "Replication Status"
+msgstr "Статус репликации"
+
 msgid "Reset Parameters"
-msgstr "Очистить параметры"
+msgstr "Сбросить параметры"
 
 msgid "Reset Root Password"
-msgstr "Сбросить пароль для root"
+msgstr "Сбросить root пароль"
 
 msgid "Resize Database Instance"
-msgstr "Изменить размер инстанса БД"
+msgstr "Изменить размер инстанса базы данных"
 
 msgid "Resize Database Volume"
 msgstr "Изменить размер диска базы данных"
@@ -925,7 +1107,7 @@ msgstr "Изменить размер и
 
 #, python-format
 msgid "Resizing volume \"%s\""
-msgstr "Изменяем размер диска \"%s\" "
+msgstr "Изменение размера диска \"%s\" "
 
 msgid "Restart Instance"
 msgid_plural "Restart Instances"
@@ -939,39 +1121,43 @@ msgstr "Требуется переза
 
 msgid "Restarted Instance"
 msgid_plural "Restarted Instances"
-msgstr[0] "Перезапущен инстанс"
-msgstr[1] "Перезапущены инстансы"
-msgstr[2] "Перезапущены инстансы"
+msgstr[0] "Инстанс перезапущен"
+msgstr[1] "Инстансы перезапущены"
+msgstr[2] "Инстансы перезапущены"
 
 msgid "Restarted instances will lose any data not saved in persistent storage."
 msgstr ""
-"Перезапущенные инстансы потеряют все данных не сохраненные в постоянном "
+"Перезапущенные инстансы потеряют все данные, не сохраненные в постоянном "
 "хранилище."
 
 msgid "Restore Backup"
-msgstr "Восстановить из резервной копии"
+msgstr "Восстановить резервную копию"
 
 msgid "Restore from Backup"
 msgstr "Восстановить из резервной копии"
 
+msgctxt "Current status of a Database Backup"
+msgid "Restored"
+msgstr "Восстановлена"
+
 msgid "Return to Log List"
-msgstr "Вернуться к списку логов"
+msgstr "Вернуться к списку журналов"
 
 msgid "Revoke Access"
 msgid_plural "Revoke Access"
-msgstr[0] "Отменить доступ"
-msgstr[1] "Отменить доступы"
-msgstr[2] "Отменить доступы"
+msgstr[0] "Отозвать доступ"
+msgstr[1] "Отозвать доступ"
+msgstr[2] "Отозвать доступ"
 
 msgid "Root Enabled"
-msgstr "Root разрешен"
+msgstr "Полный доступ включен"
 
 msgid "Root Password"
-msgstr "Пароль root"
+msgstr "Root пароль"
 
 #, python-format
 msgid "Root password updated for cluster \"%s\""
-msgstr "Пароль root обновлён для кластера \"%s\""
+msgstr "Root пароль обновлен для кластера \"%s\""
 
 msgctxt "Current status of a Database Backup"
 msgid "Saving"
@@ -980,12 +1166,12 @@ msgstr "Сохранение"
 msgid "Scheduled Shrinking of Cluster"
 msgid_plural "Scheduled Shrinking of Cluster"
 msgstr[0] "Запланировано уменьшение кластера"
-msgstr[1] "Запланировано уменьшение кластеров"
-msgstr[2] "Запланировано уменьшение кластеров"
+msgstr[1] "Запланировано уменьшение кластера"
+msgstr[2] "Запланировано уменьшение кластера"
 
 #, python-format
 msgid "Scheduled backup \"%(name)s\"."
-msgstr "Запланированная резервная копия \"%(name)s\"."
+msgstr "Запланировано резервное копирование \"%(name)s\"."
 
 msgid "Scheduled deletion of Cluster"
 msgid_plural "Scheduled deletion of Clusters"
@@ -1000,10 +1186,10 @@ msgstr[1] "Запланировано у
 msgstr[2] "Запланировано удаление инстансов"
 
 msgid "Scheduled growing of cluster."
-msgstr "Запланировано увеличение кластера"
+msgstr "Запланировано увеличение кластера."
 
 msgid "Select a backup to restore"
-msgstr "Выбрать резервную копию для восстановления"
+msgstr "Выберите резервную копию для восстановления"
 
 msgid "Select a configuration group"
 msgstr "Выберите группу конфигурации"
@@ -1015,22 +1201,22 @@ msgid "Select a master instance"
 msgstr "Выберите основной инстанс"
 
 msgid "Select a new flavor"
-msgstr "Выберите новый тип инстанса"
+msgstr "Выберите новый шаблон конфигурации"
 
 msgid "Select a parameter and provide a value for the configuration parameter."
 msgstr "Выберите параметр и предоставьте значение для параметра конфигурации."
 
 msgid "Select backup"
-msgstr "Выбрать резервную копию"
+msgstr "Выберите резервную копию"
 
 msgid "Select configuration"
-msgstr "Выбрать конфигурацию"
+msgstr "Выберите конфигурацию"
 
 msgid "Select configuration group"
 msgstr "Выберите группу конфигурации"
 
 msgid "Select datastore type and version"
-msgstr "Выбрать тип и версию хранилища данных."
+msgstr "Выберите тип и версию хранилища данных"
 
 msgid "Select instance"
 msgstr "Выберите инстанс"
@@ -1039,25 +1225,28 @@ msgid "Select networks for your instance
 msgstr "Выберите сети для вашего инстанса."
 
 msgid "Select parent backup"
-msgstr "Выбрать материнскую резервную копию"
+msgstr "Выберите родительскую резервную копию"
 
 msgid "Select the instance(s) that will be removed from the cluster."
-msgstr "Выберите инстанс(ы) который будет удален из кластера."
+msgstr "Выберите инстансы, которые будут удалены из кластера."
 
 msgid "Selected networks"
 msgstr "Выбранные сети"
 
+msgid "Service Status Updated"
+msgstr "Статус службы обновлен"
+
 msgid "Shrink Cluster"
 msgid_plural "Shrink Cluster"
 msgstr[0] "Уменьшить кластер"
-msgstr[1] "Уменьшить кластеры"
-msgstr[2] "Уменьшить кластеры"
+msgstr[1] "Уменьшить кластер"
+msgstr[2] "Уменьшить кластер"
 
 msgid "Shrink Cluster: {{cluster_name}}"
-msgstr "Уменьшать кластер: {{cluster_name}}"
+msgstr "Уменьшить кластер: {{cluster_name}}"
 
 msgid "Shrinking a cluster is not recoverable."
-msgstr "Уменьшение кластер не подлежит восстановлению."
+msgstr "Уменьшение кластера необратимо."
 
 msgctxt "Current status of a Database Instance"
 msgid "Shutdown"
@@ -1067,35 +1256,38 @@ msgid "Size"
 msgstr "Размер"
 
 msgid "Size of image to launch."
-msgstr "Размер образа для запуска"
+msgstr "Размер образа для запуска."
 
 msgid "Size of the volume in GB."
-msgstr "Размер диска в ГБ"
+msgstr "Размер диска в ГБ."
 
 msgid "Source for Initial State"
-msgstr "Источник для первоначального наполнения"
+msgstr "Источник начального состояния"
 
 msgid "Specify a new flavor for the database instance."
-msgstr "Укажите новый тип инстанса для инстанса БД."
+msgstr "Укажите новый шаблон конфигурации для инстанса базы данных."
 
 msgid "Specify a new name, new password or new host name for the user."
 msgstr "Укажите новое имя, новой пароль или новый хост для пользователя."
 
+msgid "Specify the backup strategy details."
+msgstr "Укажите подробности стратегии резервного копирования."
+
 msgid "Specify the details for launching an instance."
-msgstr "Задайте детали запуска инстанса."
+msgstr "Укажите подробности для запуска инстанса."
 
 msgid "Specify the details for the database backup."
-msgstr "Указать данные для резервной копии базы данных."
+msgstr "Укажите подробности для резервной копии базы данных."
 
 msgid "Specify the details of the instance to be added to the cluster."
-msgstr "Задайте параметры инстанса для добавления в кластер."
+msgstr "Укажите подробности инстанса для добавления в кластер."
 
 msgid ""
 "Specify the instances to be added to the cluster.  When all the instances "
 "are specified click 'Grow Cluster' to perform the grow operation."
 msgstr ""
 "Укажите инстансы для добавления в кластер. Когда все инстансы указаны, "
-"нажмите 'Увеличить кластер' для выполнения операции увеличения."
+"нажмите 'Увеличить кластер' для выполнения увеличения."
 
 msgid "Specify the name of the new database."
 msgstr "Укажите имя новой базы данных."
@@ -1107,7 +1299,7 @@ msgid "Specify the new root password for
 msgstr "Укажите новый root пароль для кластера vertica."
 
 msgid "Specify the new volume size for the database instance."
-msgstr "Указать новый размер диска для инстанса БД."
+msgstr "Укажите новый размер диска для инстанса базы данных."
 
 msgid "Specify the number of replicas to be created"
 msgstr "Укажите количество создаваемых реплик"
@@ -1118,48 +1310,63 @@ msgid ""
 "value is ignored if the instance to be launched is a replica."
 msgstr ""
 "Укажите будут ли реплицированные инстансы создаваться на одном и том же "
-"гипервизоре (аффинированность) или на разных гипервизорах (анти-"
-"аффинитивность). Это значение будет проигнорировано если запускаемый инстанс "
-"является репликой."
+"гипервизоре (affinity) или на разных гипервизорах (anti-affinity). Это "
+"значение будет проигнорировано, если запускаемый инстанс является репликой."
 
 msgid ""
 "Specify whether instances in the cluster will be created on the same "
 "hypervisor (affinity) or on different hypervisors (anti-affinity)."
 msgstr ""
 "Укажите будут ли инстансы кластера создаваться на одном и том же гипервизоре "
-"(аффинированность) или на разных (анти-аффинированность)"
+"(affinity) или на разных (anti-affinity)."
 
 msgid "Specs"
-msgstr "Спеки"
+msgstr "Спецификации"
 
 msgid "Status"
 msgstr "Статус"
 
 msgid "Status if root was ever enabled for an instance."
-msgstr "Статус если root когда либо был разрешен для инстанса."
+msgstr "Статус, если полный доступ когда-либо был включен для инстанса."
+
+msgid "Stop Database Service"
+msgid_plural "Stop Database Services"
+msgstr[0] "Остановить службу базы данных"
+msgstr[1] "Остановить службы базы данных"
+msgstr[2] "Остановить службы базы данных"
+
+msgid "Stop database service inside an instance."
+msgstr "Остановить службу базы данных внутри инстанса."
 
 msgid "Successfully added parameter"
 msgstr "Параметр успешно добавлен"
 
 msgid "Successfully disabled root access."
-msgstr "Доступ к root отключен."
+msgstr "Полный доступ успешно отключен."
+
+msgid "Swift Container"
+msgstr "Контейнер Swift"
+
+msgid "Swift Container Name"
+msgstr "Имя контейнера Swift"
 
 msgid ""
 "The 'Instance Type' and 'Related To' fields are datastore specific and "
 "optional.  See the Trove documentation for more information on using these "
 "fields."
 msgstr ""
-"Поля 'Тип инстанса' и 'Относится к' опциональны и зависят от хранилища.  "
-"Смотрите документацию Trove для подробной информации об этих полях."
+"Поля 'Тип инстанса' и 'Относится к' необязательны и зависят от типа "
+"хранилища.  Смотрите документацию Trove для подробной информации об этих "
+"полях."
 
 msgid "The flavor must be specified."
-msgstr "Должен быть указан тип инстанса."
+msgstr "Должен быть указан шаблон конфигурации."
 
 msgid ""
 "The name field is optional.   If the field is left blank a name will be "
 "generated when the cluster is grown."
 msgstr ""
-"Поле имя опциональное.   Если это поле оставить пустым, то имя будет "
+"Поле имени является опциональным.   Если поле оставить пустым, имя будет "
 "сгенерировано при увеличении кластера."
 
 msgid "The number of instances must be greater than 1."
@@ -1169,7 +1376,7 @@ msgid "The number of shards must be grea
 msgstr "Количество шардов должно быть больше 1."
 
 msgid "There was a problem enabling root."
-msgstr "Возникла проблема с разрешением пользователя root."
+msgstr "Возникла проблема с включением полного доступа."
 
 msgid "This action cannot be undone."
 msgstr "Это действие не может быть отменено."
@@ -1181,44 +1388,65 @@ msgid "Type and version of datastore."
 msgstr "Тип и версия хранилища данных."
 
 msgid "USERNAME"
-msgstr "USERNAME"
+msgstr "ИМЯ ПОЛЬЗОВАТЕЛЯ"
 
 #, python-format
 msgid "Unable to %(action)s: %(objs)s"
-msgstr "Невозможно выполнить %(action)s: %(objs)s"
+msgstr "Не удалось выполнить %(action)s: %(objs)s"
+
+msgid "Unable to add new parameter."
+msgstr "Не удалось добавить новый параметр."
+
+msgid "Unable to attach configuration group."
+msgstr "Не удалось подключить группу конфигурации."
+
+msgid "Unable to create backup strategy"
+msgstr "Не удалось создать стратегию резервного копирования"
+
+msgid "Unable to create configuration group."
+msgstr "Не удалось создать группу конфигурации."
+
+msgid "Unable to create database."
+msgstr "Не удалось создать базу данных."
 
 msgid "Unable to create list of parameters."
-msgstr "Невозможно создать список параметров."
+msgstr "Не удалось создать список параметров."
+
+msgid "Unable to create user."
+msgstr "Не удалось создать пользователя."
 
 msgid "Unable to determine if instance root is enabled."
-msgstr "Не удалось определить разрешен ли root для инстанса."
+msgstr "Не удалось определить включен ли полный доступ к инстансу."
 
 msgid "Unable to find backup!"
 msgstr "Не удалось найти резервную копию!"
 
 msgid "Unable to find configuration group!"
-msgstr "Невозможно найти группу конфигурации!"
+msgstr "Не удалось найти группу конфигурации!"
 
 msgid "Unable to find master instance!"
 msgstr "Не удалось найти основной инстанс!"
 
 msgid "Unable to get configuration data."
-msgstr "Невозможно получить данные конфигурации."
+msgstr "Не удалось получить данные конфигурации."
 
 msgid "Unable to get database backup data."
-msgstr "Не удалось получить данные резервной копии базы данных"
+msgstr "Не удалось получить данные резервной копии базы данных."
 
 msgid "Unable to get databases data."
-msgstr "Не удалось получить информацию о базах данных"
+msgstr "Не удалось получить данные баз данных."
 
 msgid "Unable to get instances data."
-msgstr "Невозможно получить данные инстансов."
+msgstr "Не удалось получить данные инстансов."
 
 msgid "Unable to get user access data."
-msgstr "Не удалось получить данные доступа пользователя"
+msgstr "Не удалось получить данные доступа пользователя."
 
 msgid "Unable to get user data."
-msgstr "Не удалось получить данные пользователя"
+msgstr "Не удалось получить данные пользователя."
+
+msgid "Unable to grow cluster."
+msgstr "Не удалось увеличить кластер."
 
 #, python-format
 msgid "Unable to grow cluster: %s"
@@ -1226,105 +1454,139 @@ msgstr "Не удалось увелич
 
 #, python-format
 msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "Не удалось запустить %(count)s названных \"%(name)s\"."
+msgstr "Не удалось запустить %(count)s с именем \"%(name)s\"."
+
+msgid "Unable to launch cluster."
+msgstr "Не удалось запустить кластер."
 
 msgid "Unable to list database backups for parent."
-msgstr "Не удалось перечислить резервные копии базы для родителя."
+msgstr "Не удалось получить список резервных копий базы данных для родителя."
 
 msgid "Unable to list database instances to backup."
 msgstr ""
 "Не удалось получить список инстансов баз данных для резервного копирования."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
 msgstr ""
-"Невозможно загрузить лог {0}\n"
+"Не удалось загрузить журнал {0}\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
-msgstr "Невозможно загрузить лог {0} для инстанса \"{1}\"."
+msgstr "Не удалось загрузить журнал {0} для инстанса \"{1}\"."
 
 msgid "Unable to obtain datastore versions."
-msgstr "Невозможно получить версии хранилищ данных."
+msgstr "Не удалось получить версии хранилищ данных."
 
 msgid "Unable to obtain datastores."
-msgstr "Невозможно получить список хранилищ данных."
+msgstr "Не удалось получить хранилища данных."
 
 msgid "Unable to obtain flavors."
-msgstr "Не удалось получить типы инстансов."
+msgstr "Не удалось получить шаблоны конфигураций."
 
 msgid "Unable to obtain information on root user"
-msgstr "Невозможно получить информацию о пользователе root"
+msgstr "Не удалось получить информацию о пользователе root"
 
 msgid "Unable to obtain list of parameters."
-msgstr "Невозможно получить список параметров."
+msgstr "Не удалось получить список параметров."
+
+msgid "Unable to promote replica as the new replica source."
+msgstr "Не удалось задать реплику новым источником реплики."
 
 #, python-format
 msgid "Unable to remove instances from cluster: %s"
-msgstr "Невозможно удалить инстансы их кластера: %s"
+msgstr "Не удалось удалить инстансы их кластера: %s"
+
+msgid "Unable to reset password."
+msgstr "Не удалось сбросить пароль."
+
+msgid "Unable to resize instance."
+msgstr "Не удалось изменить размер инстанса."
+
+msgid "Unable to resize volume."
+msgstr "Не удалось изменить размер диска."
 
 msgid "Unable to retrieve accessible databases."
 msgstr "Не удалось получить доступные базы данных."
 
 msgid "Unable to retrieve availability zones."
-msgstr "Не удалось получить список зон доступности."
+msgstr "Не удалось получить зоны доступности."
 
 msgid "Unable to retrieve cluster details."
-msgstr "Невозможно получить сведения для кластера."
+msgstr "Не удалось получить подробности кластера."
 
 msgid "Unable to retrieve database clusters."
-msgstr "Невозможно получить кластеры БД."
+msgstr "Не удалось получить кластеры базы данных."
 
 msgid "Unable to retrieve database instances."
-msgstr "Не удалось получить инстансы БД."
+msgstr "Не удалось получить инстансы базы данных."
 
 msgid "Unable to retrieve database size information."
-msgstr "Не удалось получить информацию о размере БД."
+msgstr "Не удалось получить информацию о размере базы данных."
 
 msgid "Unable to retrieve databases."
 msgstr "Не удалось получить базы данных."
 
 #, python-format
 msgid "Unable to retrieve details for backup: %s"
-msgstr "Не удалось получить подробную информацию о резервной копии: %s"
+msgstr "Не удалось получить подробности о резервной копии: %s"
 
 #, python-format
 msgid "Unable to retrieve details for configuration group: %s"
-msgstr "Не удалось получить подробную информацию о группе конфигурации: %s"
+msgstr "Не удалось получить подробности для группы конфигурации: %s"
 
 #, python-format
 msgid "Unable to retrieve details for database cluster: %s"
-msgstr "Невозможно получить сведения для кластера БД: %s"
+msgstr "Не удалось получить подробности для кластера базы данных: %s"
 
 #, python-format
 msgid "Unable to retrieve details for database instance: %s"
-msgstr "Не удалось получить детальную информацию для инстанса БД: %s"
+msgstr "Не удалось получить подробную информацию для инстанса базы данных: %s"
+
+#, python-format
+msgid "Unable to retrieve details for instance %s"
+msgstr "Не удалось получить подробности для инстанса %s"
 
 #, python-format
 msgid "Unable to retrieve details for parent backup: %s"
-msgstr "Не удалось получить данные о материнской резервной копии: %s"
+msgstr "Не удалось получить подробности о родительской резервной копии: %s"
 
 msgid "Unable to retrieve flavors."
-msgstr "Не удалось получить типы инстанса."
+msgstr "Не удалось получить шаблоны конфигураций."
 
 msgid "Unable to retrieve instance details."
-msgstr "Не удалось получить подробную информацию об инстансе."
+msgstr "Не удалось получить подробности об инстансе."
 
 #, python-format
 msgid ""
 "Unable to retrieve list of logs.\n"
 "%s"
 msgstr ""
-"Невозможно получить список логов.\n"
+"Не удалось получить список журналов.\n"
 "%s"
 
 msgid "Unable to retrieve networks."
 msgstr "Не удалось получить сети."
 
+#, python-format
+msgid "Unable to update instance \"%s\"."
+msgstr "Не удалось обновить инстанс \"%s\"."
+
+msgid "Unable to update user."
+msgstr "Не удалось обновить пользователя."
+
 msgid "Unknown"
 msgstr "Неизвестно"
 
+msgid "Update Instance"
+msgstr "Обновить инстанс"
+
+msgid "Update instance."
+msgstr "Обновить инстанс."
+
 msgid "Updated"
 msgstr "Обновлено"
 
@@ -1335,6 +1597,9 @@ msgstr "Обновлен пользов
 msgid "User Name"
 msgstr "Имя пользователя"
 
+msgid "User defined swift container name."
+msgstr "Имя Swift контейнера, заданное пользователем."
+
 msgid "Username (required)"
 msgstr "Имя пользователя (обязательно)"
 
@@ -1370,10 +1635,10 @@ msgid "Values"
 msgstr "Значения"
 
 msgid "View Full Log"
-msgstr "Просмотр полного лога"
+msgstr "Просмотр полного журнала"
 
 msgid "View Log"
-msgstr "Просмотреть лог"
+msgstr "Просмотреть журнал"
 
 msgid "Volume"
 msgstr "Диск"
@@ -1386,28 +1651,31 @@ msgstr "Тип диска"
 
 #, python-format
 msgid "You are not allowed to %(action)s: %(objs)s"
-msgstr "Вам не разрешено выполнение: %(action)s: %(objs)s"
+msgstr "Вам запрещено выполнение %(action)s: %(objs)s"
 
 msgid ""
 "You can perform an incremental backup by specifying a parent backup. "
 "<strong>However,</strong> not all databases support incremental backups in "
 "which case this operation will result in an error."
 msgstr ""
-"Вы можете выполнить инкрементное резервное копирование, указав материнскую "
-"резервную копию. <strong>Однако, </strong> не все базы данных поддерживают "
-"инкрементное резервное копирование, в этом случае операция приведёт к ошибке."
+"Вы можете выполнить инкрементальное резервное копирование, указав "
+"материнскую резервную копию. <strong>Однако, </strong> не все базы данных "
+"поддерживают инкрементальное резервное копирование, в этом случае операция "
+"приведёт к ошибке."
 
 msgid "You must select a datastore type and version."
-msgstr "Вы должны выбрать тип и версию хранилища данных."
+msgstr "Вам необходимо выбрать тип и версию хранилища данных."
 
 msgid "You must select a flavor."
-msgstr "Необходимо выбрать тип инстанса."
+msgstr "Вам необходимо выбрать шаблон конфигурации."
 
 msgid "You must specify a password if you create a user."
-msgstr "Вы должны задать пароль если хотите создать пользователя."
+msgstr "Вы должны задать пароль, если хотите создать пользователя."
 
 msgid "You must specify at least one database if you create a user."
-msgstr "Вы должны создать по крайней мере одну БД если создаете пользователя."
+msgstr ""
+"Вы должны создать по крайней мере одну базу данных если создаете "
+"пользователя."
 
 #, python-format
 msgid ""
diff -pruN 24.0.0-1/trove_dashboard/locale/ru/LC_MESSAGES/djangojs.po 25.0.0~rc1-1/trove_dashboard/locale/ru/LC_MESSAGES/djangojs.po
--- 24.0.0-1/trove_dashboard/locale/ru/LC_MESSAGES/djangojs.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/ru/LC_MESSAGES/djangojs.po	2025-09-09 03:44:01.000000000 +0000
@@ -1,19 +1,21 @@
 # Maxim Bozhenko <mbozhenko@gmail.com>, 2016. #zanata
+# Dmitriy Chubinidze <dcu995@gmail.com>, 2025. #zanata
+# Ivan Anfimov <lazekteam@gmail.com>, 2025. #zanata
 msgid ""
 msgstr ""
-"Project-Id-Version: trove-dashboard 7.0.0.0rc2.dev7\n"
+"Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2016-10-07 13:57+0000\n"
+"POT-Creation-Date: 2025-06-19 11:56+0300\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2016-09-28 02:47+0000\n"
-"Last-Translator: Maxim Bozhenko <mbozhenko@gmail.com>\n"
+"PO-Revision-Date: 2025-04-01 09:43+0000\n"
+"Last-Translator: Dmitriy Chubinidze <dcu995@gmail.com>\n"
 "Language-Team: Russian\n"
 "Language: ru\n"
-"X-Generator: Zanata 3.7.3\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"X-Generator: Zanata 4.3.3\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
 
 msgid "Created"
 msgstr "Создано"
@@ -22,10 +24,10 @@ msgid "Database"
 msgstr "База данных"
 
 msgid "Datastore"
-msgstr "Хранилище"
+msgstr "Тип хранилища"
 
 msgid "Datastore Version"
-msgstr "Версия хранилища"
+msgstr "Версия типа хранилища"
 
 msgid "Incremental"
 msgstr "Инкрементальный"
@@ -34,7 +36,7 @@ msgid "Name"
 msgstr "Имя"
 
 msgid "Unable to retrieve the Backups."
-msgstr "Невозможно получить резервные копии."
+msgstr "Не удалось получить резервные копии."
 
 msgid "status"
-msgstr "Статус"
+msgstr "статус"
diff -pruN 24.0.0-1/trove_dashboard/locale/tr_TR/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/tr_TR/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/tr_TR/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/tr_TR/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -603,9 +603,6 @@ msgstr "%(count)s \"%(name)s\" isimli ba
 msgid "Launched cluster \"%s\""
 msgstr "\"%s\" kümesi başlatıldı"
 
-msgid "Locality"
-msgstr "Çevre"
-
 msgid "Log"
 msgstr "Günlük"
 
@@ -618,9 +615,6 @@ msgstr "Günlük Uzunluğu"
 msgid "Log length must be a nonnegative integer."
 msgstr "Günlük uzunluğu negatif olmayan tam sayı olmalı."
 
-msgid "Log: "
-msgstr "Günlük: "
-
 msgid "Logs"
 msgstr "Günlükler"
 
@@ -734,12 +728,6 @@ msgstr "Parça Sayısı"
 msgid "Number of instances in the cluster."
 msgstr "Kümedeki sunucu sayısı."
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "Kümedeki sunucu sayısı. (Salt okunur)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Parça sayısı. (Salt okunur)"
-
 msgid "Old Flavor"
 msgstr "Eski Nitelik"
 
@@ -831,12 +819,6 @@ msgid ""
 msgstr ""
 "Parola yalnızca root etkinleştirildiğinde ya da sıfırlandığında görünür."
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr ""
-"Lütfen dikkat.</strong>Yeni değer mevcut birim boyutundan büyük olmalı."
-
 msgid "Promote"
 msgstr "Terfi et"
 
@@ -1234,6 +1216,7 @@ msgstr "Üst için veritabanı yedekleri
 msgid "Unable to list database instances to backup."
 msgstr "Yedek alınacak veritabanı sunucuları listelenemedi."
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1241,6 +1224,7 @@ msgstr ""
 "{0} günlüğü yüklenemedi\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "\"{1}\" sunucusu için {0} günlüğü yüklenemedi."
 
diff -pruN 24.0.0-1/trove_dashboard/locale/zh_Hans/LC_MESSAGES/django.po 25.0.0~rc1-1/trove_dashboard/locale/zh_Hans/LC_MESSAGES/django.po
--- 24.0.0-1/trove_dashboard/locale/zh_Hans/LC_MESSAGES/django.po	2025-02-09 11:31:17.000000000 +0000
+++ 25.0.0~rc1-1/trove_dashboard/locale/zh_Hans/LC_MESSAGES/django.po	2025-09-09 03:44:01.000000000 +0000
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: trove-dashboard VERSION\n"
 "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-04-29 11:18+0000\n"
+"POT-Creation-Date: 2025-09-08 09:00+0000\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -586,9 +586,6 @@ msgstr "启动了%(count)s 名称\"%(nam
 msgid "Launched cluster \"%s\""
 msgstr "启动集群\"%s\""
 
-msgid "Locality"
-msgstr "地域"
-
 msgid "Log"
 msgstr "日志"
 
@@ -601,9 +598,6 @@ msgstr "日志长度"
 msgid "Log length must be a nonnegative integer."
 msgstr "日志长度必须为非负整数值。"
 
-msgid "Log: "
-msgstr "日志："
-
 msgid "Logs"
 msgstr "日志"
 
@@ -720,12 +714,6 @@ msgstr "Shard数"
 msgid "Number of instances in the cluster."
 msgstr "集群中的云主机数量。"
 
-msgid "Number of instances in the cluster. (Read only)"
-msgstr "集群中的实例数。(只读)"
-
-msgid "Number of shards. (Read only)"
-msgstr "Shard数。（只读）"
-
 msgid "Old Flavor"
 msgstr "旧的云主机类型"
 
@@ -805,11 +793,6 @@ msgid ""
 "Password is only visible immediately after the root is enabled or reset."
 msgstr "在root启用或重置时，密码只能临时可用。"
 
-msgid ""
-"Please note:</strong> The new value must be greater than the existing volume "
-"size."
-msgstr "请注意：</strong>新卷容量大小必须大于当前卷容量大小"
-
 msgid "Promote"
 msgstr "设置"
 
@@ -1189,6 +1172,7 @@ msgstr "无法获取用来做母版的
 msgid "Unable to list database instances to backup."
 msgstr "无法获取数据库实例进行备份。"
 
+#, python-brace-format
 msgid ""
 "Unable to load {0} log\n"
 "{1}"
@@ -1196,6 +1180,7 @@ msgstr ""
 "无法加载{0} 日志\n"
 "{1}"
 
+#, python-brace-format
 msgid "Unable to load {0} log for instance \"{1}\"."
 msgstr "无法加载实例\"{1}\"的日志{0}"
 
