././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/0000775000175000017500000000000000000000000013470 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/.coveragerc0000664000175000017500000000017600000000000015615 0ustar00zuulzuul00000000000000[run] branch = True source = manila_ui omit = manila_ui/enabled*,manila_ui/test* [report] precision = 2 ignore_errors = True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/.mailmap0000664000175000017500000000013000000000000015103 0ustar00zuulzuul00000000000000# Format is: # # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/.testr.conf0000664000175000017500000000047600000000000015565 0ustar00zuulzuul00000000000000[DEFAULT] test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/.zuul.yaml0000664000175000017500000001064500000000000015437 0ustar00zuulzuul00000000000000- project: templates: - check-requirements - horizon-non-primary-django-jobs - openstack-cover-jobs-horizon - openstack-python3-jobs-horizon - publish-openstack-docs-pti - release-notes-jobs-python3 check: jobs: - openstack-tox-cover: voting: false - manila-ui-integration-tests: voting: false gate: jobs: - manila-ui-integration-tests: voting: false - job: name: manila-ui-integration-tests parent: horizon-integration-tests required-projects: - name: openstack/horizon - name: openstack/manila - name: openstack/python-manilaclient - name: openstack/manila-ui - name: openstack/manila-tempest-plugin roles: - zuul: openstack/devstack - zuul: openstack/horizon irrelevant-files: - ^.*\.rst$ - ^doc/.*$ - ^releasenotes/.*$ vars: devstack_localrc: USE_PYTHON3: true # Enable manila with a fake driver that supports all capabilities MANILA_CONFIGURE_DEFAULT_TYPES: true MANILA_OPTGROUP_DEFAULT_quota_share_networks: 50 MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS: 'snapshot_support=True create_share_from_snapshot_support=True revert_to_snapshot_support=True mount_snapshot_support=True' MANILA_INSTALL_TEMPEST_PLUGIN_SYSTEMWIDE: false MANILA_SERVICE_IMAGE_ENABLED: false MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL: 1 SHARE_DRIVER: manila.tests.share.drivers.dummy.DummyDriver MANILA_REPLICA_STATE_UPDATE_INTERVAL: 10 MANILA_ENABLED_BACKENDS: alpha,beta,gamma,delta MANILA_CONFIGURE_GROUPS: alpha,beta,gamma,delta,membernet,adminnet MANILA_OPTGROUP_alpha_share_driver: manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_alpha_driver_handles_share_servers: true MANILA_OPTGROUP_alpha_share_backend_name: ALPHA MANILA_OPTGROUP_alpha_network_config_group: membernet MANILA_OPTGROUP_alpha_admin_network_config_group: adminnet MANILA_OPTGROUP_alpha_replication_domain: DUMMY_DOMAIN_2 MANILA_OPTGROUP_beta_share_driver: manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_beta_driver_handles_share_servers: true MANILA_OPTGROUP_beta_share_backend_name: BETA MANILA_OPTGROUP_beta_network_config_group: membernet MANILA_OPTGROUP_beta_admin_network_config_group: adminnet MANILA_OPTGROUP_beta_replication_domain: DUMMY_DOMAIN_2 MANILA_OPTGROUP_gamma_share_driver: manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_gamma_driver_handles_share_servers: false MANILA_OPTGROUP_gamma_share_backend_name: GAMMA MANILA_OPTGROUP_gamma_replication_domain: DUMMY_DOMAIN MANILA_OPTGROUP_delta_share_driver: manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_delta_driver_handles_share_servers: false MANILA_OPTGROUP_delta_share_backend_name: DELTA MANILA_OPTGROUP_delta_replication_domain: DUMMY_DOMAIN MANILA_OPTGROUP_membernet_network_api_class: manila.network.standalone_network_plugin.StandaloneNetworkPlugin MANILA_OPTGROUP_membernet_standalone_network_plugin_gateway: 10.0.0.1 MANILA_OPTGROUP_membernet_standalone_network_plugin_mask: 24 MANILA_OPTGROUP_membernet_standalone_network_plugin_network_type: vlan MANILA_OPTGROUP_membernet_standalone_network_plugin_segmentation_id: 1010 MANILA_OPTGROUP_membernet_standalone_network_plugin_allowed_ip_ranges: 10.0.0.10-10.0.0.209 MANILA_OPTGROUP_membernet_network_plugin_ipv4_enabled: true MANILA_OPTGROUP_adminnet_network_api_class: manila.network.standalone_network_plugin.StandaloneNetworkPlugin MANILA_OPTGROUP_adminnet_standalone_network_plugin_gateway: 11.0.0.1 MANILA_OPTGROUP_adminnet_standalone_network_plugin_mask: 24 MANILA_OPTGROUP_adminnet_standalone_network_plugin_network_type: vlan MANILA_OPTGROUP_adminnet_standalone_network_plugin_segmentation_id: 1011 MANILA_OPTGROUP_adminnet_standalone_network_plugin_allowed_ip_ranges: 11.0.0.10-11.0.0.19,11.0.0.30-11.0.0.39,11.0.0.50-11.0.0.199 MANILA_OPTGROUP_adminnet_network_plugin_ipv4_enabled: true devstack_plugins: manila: https://opendev.org/openstack/manila manila-ui: https://opendev.org/openstack/manila-ui devstack_services: horizon: true tox_envlist: integration ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/AUTHORS0000664000175000017500000000640400000000000014544 0ustar00zuulzuul00000000000000Adrian Fusco Arnejo Akihiro Motoki Akshai Parthasarathy Andreas Jaeger Arne Wiebalck Ben Swartzlander Cameron Kolodjski Charles Short Christoph Fiehe Chuck Short Corey Bryant Dina Saparbaeva Dina Saparbaeva Doug Hellmann Dustin Schoenbrun Flavio Percoco Gary W. Smith Ghanshyam Mann Gloria Gu Goutham Pacha Ravi Goutham Pacha Ravi Hangdong Zhang Hassan Asghar Ian Wienand Igor Malinovskiy Ivan Kolodyazhny Jeremy Liu Julia Varlamova M V P Nitesh Maari Tamm Mateusz Kowalski Miriam Yumi Monty Taylor Nguyen Hung Phuong OpenStack Release Bot Ponomaryov Valeriy Qian Min Chen Ramana Raja Rich Hagarty Rich Hagarty Rishabh Dave Robin Cernin Rodrigo Barbieri Sergey Gotliv ShangXiao Sharat Sharma Takashi Kajinami Takashi Kajinami Tatiana Ovchinnikova Thomas Bechtold Tom Barron Vadym Markov Valeriy Ponomaryov Victoria Martinez de la Cruz Victoria Martinez de la Cruz Vieri <15050873171@163.com> Vitaliy Levitski Vu Cong Tuan Zhenguo Niu aditi bhavani.cr blue55 dengzhaosen gujin haixin hparekh huang.zhiping jacky06 liyifeng <307419146@qq.com> luqitao maaoyu manchandavishal mark.sturdevant melakualehegn melissaml pengyuesheng reedip ricolin sehun.jeong silvacarloss vponomaryov vrushti wanghui wu.shiming zhangbailin zhangyanxian zhongjun zzxwill ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/CONTRIBUTING.rst0000664000175000017500000000114300000000000016130 0ustar00zuulzuul00000000000000The source repository for this project can be found at: https://opendev.org/openstack/manila-ui Pull requests submitted through GitHub are not monitored. To start contributing to OpenStack, follow the steps in the contribution guide to set up and use Gerrit: https://docs.openstack.org/contributors/code-and-documentation/quick-start.html Bugs should be filed on Launchpad: https://bugs.launchpad.net/manila-ui For more specific information about contributing to this repository, see the manila-ui contributor guide: https://docs.openstack.org/manila-ui/latest/contributor/contributing.html ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/ChangeLog0000664000175000017500000005224100000000000015246 0ustar00zuulzuul00000000000000CHANGES ======= 11.0.0 ------ * reno: Update master for unmaintained/xena * reno: Update master for unmaintained/wallaby * reno: Update master for unmaintained/victoria * Add new-note tox environment * Create share network panel workflows * reno: Update master for unmaintained/yoga * Bump hacking * Update python classifier in setup.cfg * Remove unused babel.cfg * Avoid server error caused by UnicodeDecodeError * Fix python shebang * Update master for stable/2023.2 10.0.0 ------ * Imported Translations from Zanata * Fix test failures with Django 4.x * Remove empty choices added to required fields * Imported Translations from Zanata * Imported Translations from Zanata * Update master for stable/2023.1 9.0.0 ----- * Fix "Set as Active" button's display for replicas * Fix coverage job from running with tox4 * Imported Translations from Zanata * Support capital letter in share type name * Fix getting len() attr from boolean values * Add update share-type name description and/or public access * Imported Translations from Zanata * tox: Declare bash as allowlist\_externals * Update \`\`bindep.txt\`\` to sync with the horizon * Imported Translations from Zanata * Switch to 2023.1 Python3 unit tests and generic template name * Update master for stable/zed 8.0.0 ----- * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Drop lower-constraints.txt and its testing * Fix share replica creation * Use gettext\_lazy/ngettext\_lazy instead of ugettext\_lazy/ungettext\_lazy * Workaround SDK bug in listing shares * Use re\_path instead of url * Add Python3 zed unit tests * Update master for stable/yoga 7.0.0 ----- * Update python-manilaclient and horizon required * Add platform annotation in bindep.txt * Update python testing classifier * Add Python3 yoga unit tests * Update master for stable/xena 6.0.0 ----- * Follow up patch for API v2.45, fixes bug on rule metadata form * API v2.46, added 'is\_default' field to share group types * API v2.46, added 'is\_default' field to share types * API v2.45, adds metadata support to access rules * Set parent share az when creating a share from snapshot * Changed minversion in tox to 3.18.0 * Fix share group creation with share types * [CI] Temporarily set integration test job to non-voting * Fix parsing names in switched fields * setup.cfg: Replace dashes with underscores * Remove nova networking * Support policy-in-code and deprecated policy * Add Python3 xena unit tests * Update master for stable/wallaby 5.0.0.0rc1 ---------- * follow up fix to share-shrinking * API v2.44, added 'ou' field to security service * filter search by extra spec for share type list * Add example of logging setting for Manila * Addition of share shrinking feature to Manila-UI * remove unicode from code * Imported Translations from Zanata * Define the default policy file * tox miniversion update to 3.1.1 * Updates testenv to py38 and removes RIZON\_INTEGRATION\_TESTS\_CONFIG\_FILE * Use TOX\_CONSTRAINTS\_FILE * API v2.41, create share type with description * Adds "message\_level" to user messages panel * Update requirements * API v2.40, share groups quotas * Add py38 package metadata * Imported Translations from Zanata * Imported Translations from Zanata * Improve label for Share Update Form * Changes to Share Update Functionality in Manila UI * Imported Translations from Zanata * Add Python3 wallaby unit tests * Update master for stable/victoria 4.0.0 ----- * Remove install unnecessary packages * Improve unit test coverage for manila.py * Make \`\`cover\`\` job non-voting * User messages panel * tox: specify ignore\_basepython\_conflict * [goal] Migrate testing to ubuntu focal * Drop legacy dsvm job & change zuulv3 integration job * Switch to newer openstackdocstheme and reno versions * Fix hacking min version to 3.0.1 * TrivialFix: Remove unnecessary future import * Imported Translations from Zanata * Imported Translations from Zanata * Add Python3 victoria unit tests * Update master for stable/ussuri * [ussuri][goal] Change contributor guide * Imported Translations from Zanata * Drop install\_command usage in tox * Imported Translations from Zanata 3.0.0 ----- * Remove mock from requirements * Cleanup py27 support * Imported Translations from Zanata * Add pytest to test-requirements * Add support for API version 2.38 * Imported Translations from Zanata * Imported Translations from Zanata * Add support for API version 2.34 * Fix pyScss version in lower-constraints.txt * Use unittest.mock instead of third party mock * Update hacking for Python3 * Add availability zone field for public shares * Add missing translation support markings * Raise python-manilaclient req to 1.29.0 * Update API version to 2.33 * Imported Translations from Zanata * Remove six usage * Drop Django 1.11 support * translation: drop babel extractor definitions * Error handling: Use exceptions.handle instead of check\_message * Imported Translations from Zanata * Imported Translations from Zanata * Drop python2.7 support * Drop snapshot\_support param from share\_type\_create * Change Ussuri python jobs template * Switch to Ussuri jobs * Use Horizon project template for django jobs * Switch from django string\_concat to format\_lazy * Imported Translations from Zanata * Update the constraints url * Imported Translations from Zanata * Update master for stable/train 2.19.0 ------ * Add PDF documentation build * Updated to get quotas data for Modify Quotas dialog Share tab * Replace the old-operator in installation docs * Limit envlist to py37 for Python 3 Train goal * Use openstack-python3-train-jobs for python3 test runtime * Modify the url of upper\_constraints\_file * Remove the get\_item method * Update sphinx dependency * Replace git.openstack.org URLs with opendev.org URLs * OpenDev Migration Patch * Add Python 3.6 and Python 3.7 jobs * Dropping the py35 testing * Update master for stable/stein 2.18.0 ------ * Fix share replica details page for non-admins * Don't show host field in project tables * Add share servers to share network detail * Show share network details to non-admin * Replace openstack.org git:// URLs with https:// * base job has changed to bionic * Imported Translations from Zanata * [CI] Run integration tests with tls-proxy * Add manila-ui integration tests 2.17.0 ------ * Run dsvm job under python3 * Update hacking version * migrate legacy job to bionic * Imported Translations from Zanata * Change openstack-dev to openstack-discuss * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * fix tox python3 overrides * Imported Translations from Zanata * Imported Translations from Zanata * Add ability to test Manila UI with Horizon master branch * Use templates for cover and lower-constraints * Remove dead code * switch documentation job to new PTI * import zuul job settings from project-config * Fix location for coverage reports * Imported Translations from Zanata * Drop nose dependencies * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Use 'trimmed' for blocktrans in multi-line strings * Update reno for stable/rocky 2.16.0 ------ * Imported Translations from Zanata * Fix quotas retrieval for shares and snapshots tables * Remove use\_mox directive * Drop Django depdency from requirements.txt * Update the home-page link * Add Apple OS X ".DS\_Store" to ".gitignore" file * Add line for PyCharm IDE in gitignore file * Add py36 testenv * fix tox python3 overrides * Update installation docs for Manila UI * Imported Translations from Zanata * Add python3 django 1.11 job instead of django 2.0 job 2.15.0 ------ * Consume py35 project template from project-config * Remove unnecessary noqa * Fix UT failures due to horizon tenant\_limit\_usages drop * Imported Translations from Zanata * Require the (soon-to-be) Rocky version of Horizon * Add release notes link to README * Imported Translations from Zanata * Imported Translations from Zanata * Django 2.0 support * Remove try-catch from test\_data imports * Make manila-ui python3 compatible * Imported Translations from Zanata * add lower-constraints job * Fix warnings on py27 environment 2.14.0 ------ * Imported Translations from Zanata * Imported Translations from Zanata * Move the job manila-ui-dsvm in-tree * Updated from global requirements * Use EXTRA\_TABS/EXTRA\_STEPS mechanism to handle manila quotas * Update links in README * Add horizon to requirements * Imported Translations from Zanata * Updated from global requirements * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Update reno for stable/queens * Imported Translations from Zanata * Correct django template pattern in babel-django.cfg * Updated from global requirements * Imported Translations from Zanata 2.13.0 ------ * Imported Translations from Zanata * Updated from global requirements * Import user and admin guide from horizon * Reorganize manila-ui documentation * Remove empty files * Updated from global requirements 2.12.0 ------ * Remove setting of version/release from releasenotes * Updated from global requirements * Drop django\_openstack\_auth from requirements.txt * Updated from global requirements 2.11.0 ------ * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Fix quota bars in Create Share panel * Updated from global requirements * Imported Translations from Zanata * Add quota.type field when reporting share usage * Manila-UI breaks Horizon's "Network" panel group * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * doc migration: warning-is-error * Update reno for stable/pike * doc migration: new directory layout * doc migration: openstackdocstheme * Imported Translations from Zanata * Updated from global requirements 2.10.1 ------ * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Optimize the link address * Imported Translations from Zanata * Updated from global requirements * Imported Translations from Zanata 2.10.0 ------ * Add support of share groups * Imported Translations from Zanata * Updated from global requirements * Update URLs in documentation * Updated from global requirements * Imported Translations from Zanata * Updated from global requirements * Imported Translations from Zanata * Update .gitignore to ignore .eggs * Imported Translations from Zanata * Enable some off-by-default checks * Imported Translations from Zanata * Some tweaks for modal forms 2.9.0 ----- * Imported Translations from Zanata * Refactor project dashboard * Refactor admin dashboard * Fix compatibility with latest horizon * Use parse\_isotime filters for Share Replicas table columns * Updated from global requirements * Imported Translations from Zanata * Imported Translations from Zanata * Updated from global requirements * Fix compatibility with Horizon * Updated from global requirements * Imported Translations from Zanata * Fix NotImplementedError and use new way to define action\_present/past * Fix 'cover' tox job * Fix manila quota operations * Fix share creation from snapshot * Add possibility to revert a share to a snapshot * Update tox envlist * Updated from global requirements * Imported Translations from Zanata * Updated from global requirements * Imported Translations from Zanata 2.8.0 ----- * Updated from global requirements * Updated from global requirements * Imported Translations from Zanata * Imported Translations from Zanata * Clean docs/build before building docs * Fix 2 CI breakages * Updated from global requirements * Update test requirement * Correct the actual path for setting DJANGO\_SETTINGS\_MODULE * Imported Translations from Zanata * Updated from global requirements * Imported Translations from Zanata * Imported Translations from Zanata * Fix Manage Replicas button availability * Imported Translations from Zanata * Imported Translations from Zanata * Imported Translations from Zanata * Remove link to modindex * Update reno for stable/ocata 2.7.0 ----- * Add mountable snapshots support to manila-ui * Imported Translations from Zanata * Updated from global requirements * Updated from global requirements * Implement Share Migration Ocata improvements * Bump microversion to 2.26 * Add MapRFS protocol 2.6.0 ----- * Updated from global requirements * Changed the home-page of manila-ui * Imported Translations from Zanata * Update settings file with all available config options * Only show available share protocols on share creation modal * Disable creation of public shares per configuration * Fix some typos in cover.sh * Ignore current share's size in extend quota bar * Moves OPENSTACK\_MANILA\_SETTINGS TO local\_settings.d/ * Imported Translations from Zanata * Updated from global requirements * Add access key column to rules table * Show team and repo badges on README * Imported Translations from Zanata * Adds Manila-UI Devstack plugin * Update README.rst file with more info * Imported Translations from Zanata * Updated from global requirements * Updated from global requirements * Updated from global requirements * Imported Translations from Zanata * Imported Translations from Zanata * Updated from global requirements * Imported Translations from Zanata * Updated from global requirements * Enable release notes translation * Updated from global requirements * Fix broken unit tests * Fix metadata\_to\_str function code injection vulnerability * Fix migration-start id-dependent form * Fix display of Delete share replica button * Clean imports in code * Update reno for stable/newton * Imported Translations from Zanata * Read list of AZs using manila's API instead of nova's * Imported Translations from Zanata * Change Create Replica button availability 2.5.0 ----- * Add share type change to Share Migration UI * Add Share Migration support * Add share replication support 2.4.0 ----- * [Trivial] Fix Share Network details field * Fix tables layout * Use upper constraints in tox installs * Imported Translations from Zanata * Disable creation of public share types per configuration * Updated from global requirements * Fix py27 and py27dj19 gates * Updated from global requirements * Fix get\_disabled\_quotas * Correct typo * Update Django 1.10 tox env * Fix Django 1.9 unit tests * Delete openstack/common from the exclude list of flake8 in tox * Remove unit tests warnings * Imported Translations from Zanata * Updated from global requirements * Table actions improvement * Remove Cinder leftovers from Create Snapshot View * Fix improperly rendered Create Snapshot modal form * Remove incorrect docstrings * Update Share Metadata modal form refactoring * Fix unit tests for Django 1.9 * Register apps in unit tests properly * Fix unit tests * Updated from global requirements * Fix improperly rendered Edit Share modal form * Fix improperly rendered Update Security Service modal form 2.3.0 ----- * Fix Edit Snapshot action * Remove vim headers * Updated from global requirements * Unit test for Create Share Type * Updated from global requirements * Update Share Snapshot modal form refactoring * Create Share Snapshot modal form refactoring * Imported Translations from Zanata * Extend Share and Add Rule modals refactoring * Fix error handling for 'extend' share operation * Updated from global requirements * Updated from global requirements * Fix py27 tox job * Clean Update Share Type modal form * Clean Shares modal forms * Clean Security Services modal forms * Imported Translations from Zanata * Clean Create Share Network modal form * Clean Create Share Type modal form * Remove discover from test-requirements * Add RDO install instructions for Manila UI * Updated from global requirements 2.2.0 ----- * Imported Translations from Zanata * Updated from global requirements * Updated from global requirements * Add support for releasenotes * Create private share types * Imported Translations from Zanata * Cleanup of CreateShareType form * Update HTML template for snapshot detailed page * Update HTML template for share network detailed page * Update HTML template for security service detailed page * Imported Translations from Zanata * Updated from global requirements * Fix usages view on project/overview page * Update detailed page for share servers * Fix mocks in unit tests * Remove redundant API calls from admin dashboard * Add share instances tab to admin dashboard * Updated from global requirements * Add 'cephx' access type * Enable translation for manila-ui * Updated from global requirements * Register Manilaclient exceptions in Horizon * Updated from global requirements * Use latest Manila API microversion * Place all unit tests under single subdir * Make 'cover' job use always venv * Upgrade coverage tox job * Updated from global requirements 2.1.0 ----- * Updated from global requirements 2.0.0 ----- * Updated from global requirements * Fix compatibility with Manilaclient and Horizon * remove python 3.3 trove classifier * Drop MANIFEST.in - it's not needed with PBR * Remove "builtins = \_" from tox.ini * remove python 2.6 trove classifier * Can not create a LDAP security-service with no auth * Remove import of unnecessary modules from Horizon * Fix call to Client() with 2 api\_version args * Updated from global requirements * Remove unused Manila API methods * Updated from global requirements * Use "GiB" and "gibibyte" labels in share panels * Updated from global requirements * Updated from global requirements 1.2.0 ----- * Updated from global requirements * Change ignore-errors to ignore\_errors * Use v2 API of Manila * Updated requirements and unit tests config * Disable button 'create snapshot' if share not snapshottable * Fix broken unit test * Add availability zones support to manila-ui * Fix set/unset extra specs for share type update form * Remove overrides reference from Manila-UI plug-in * Add extend support to manila-ui * Fix breakage of unit tests * Switch to post-versioning 1.1.0 ----- * Fix broken unit tests * Remove usage of openstack.common.\_i18n module * Add mock manilaclient to APITestCase class * Use UPDATE\_HORIZON\_CONFIG for manila\_ui.overrides * Show test names and results instead of "." and "S" * Set new address of manila-ui repo in file README.rst * Add .gitreview file for manila-ui * Set version number to 1.1.0 * Fix AttrError on share creation form with django 1.6-1.7 * Fix pep8 violations * Make status values translatable * Upgrade to django 1.7 * Reduce title duplication, concatenation in Project Shares * Fix pep8 violations * Remove horizon patch installation from README * Remove unused templates * Reduce title duplication, concatenation in Admin Shares * Enable unit testing via tox * Update unit test instructions in README * Remove unused unit test code * Skip broken unit tests * Fix pep8 violations via run\_tests.sh -p * Enable unit tests to run standalone * Include unit test instructions * Remove broken links from README * Revert "Fix error referencing missing attribute" * Adjust expected strings * Fix error referencing missing attribute * Fix metadata conversion * Expect exception properly * Add missing mock calls * Resolve unit test failures from missing keystone data * Ignore secret key lock files * Enable unit tests to resolve urls properly * Bump manilaclient version to 1.0.4 * Fix two typos in share network messages * Fix pep8 violations * Add nova-network support to share-networks of Manila * Open Liberty development * Add version into setup.cfg * Update README to include needed horizon patch * Add installation instructions * Pull all snapshots on admin tab * Make share name in 'manage' form optional * Update share type creation form * Switch couple of elements on share creation form * Display attr 'host' on share detailed page * Fix view of projects selection for private share types * Fix appearance of share delete button in projects tab * Add attr 'has\_snapshot' for each share in share table * Add support of API manage/unmanage for Manila * Add support for setting of share type access * Make tab 'Share Types' starting from both capitals * Add posibility to set visibility attr for share types * Add support of 'is\_public' attr for shares * Show all export locations on share detail page * Fix view of metadata on shares tab * Add links to snapshot and share network on shares detailed page * Fix share creation form when share\_type is not provided * Rename deprecated "sid" to "user" (security services for shares) * Fix access rules handling * Remove logic that was moved into override.py * Change overview label to "Share Networks" * Incoporate get\_item filter * Enable full quota, overview functionality * Get quotas working enough to permit creating shares * Remove unused references to mox * Initial attempt to get unit tests working * Fix pep8 violations * Enable projects, admin panels to load * Import code from manila\_kilo branch of manila UI * Initial project creation ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/HACKING.rst0000664000175000017500000000021400000000000015263 0ustar00zuulzuul00000000000000manila-ui Style Commandments ============================ Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/LICENSE0000664000175000017500000002363600000000000014507 0ustar00zuulzuul00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/PKG-INFO0000664000175000017500000000343700000000000014574 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: manila-ui Version: 11.0.0 Summary: Manila Management Dashboard Home-page: https://docs.openstack.org/manila-ui/latest/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: Team and repository tags ------------------------ .. image:: https://governance.openstack.org/tc/badges/manila-ui.svg :target: https://governance.openstack.org/tc/reference/tags/index.html .. Change things from this point on ======================================= manila-ui - Manila Management Dashboard ======================================= * Free software: Apache license * Documentation: https://docs.openstack.org/manila-ui/latest/ * Release notes: https://docs.openstack.org/releasenotes/manila-ui/ * Source: https://opendev.org/openstack/manila-ui * Bugs: https://bugs.launchpad.net/manila-ui Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Requires-Python: >=3.6 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/README.rst0000664000175000017500000000114200000000000015155 0ustar00zuulzuul00000000000000Team and repository tags ------------------------ .. image:: https://governance.openstack.org/tc/badges/manila-ui.svg :target: https://governance.openstack.org/tc/reference/tags/index.html .. Change things from this point on ======================================= manila-ui - Manila Management Dashboard ======================================= * Free software: Apache license * Documentation: https://docs.openstack.org/manila-ui/latest/ * Release notes: https://docs.openstack.org/releasenotes/manila-ui/ * Source: https://opendev.org/openstack/manila-ui * Bugs: https://bugs.launchpad.net/manila-ui ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/babel-django.cfg0000664000175000017500000000011500000000000016453 0ustar00zuulzuul00000000000000[python: **.py] [django: **/templates/**.html] [django: **/templates/**.csv] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/babel-djangojs.cfg0000664000175000017500000000006100000000000017010 0ustar00zuulzuul00000000000000[javascript: **.js] [angular: **/static/**.html] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/bindep.txt0000664000175000017500000000102300000000000015466 0ustar00zuulzuul00000000000000# selenium tests firefox [selenium platform:ubuntu] firefox-esr [selenium platform:debian] xvfb [selenium platform:dpkg] # already part of xorg-x11-server on openSUSE xorg-x11-server-Xvfb [selenium platform:redhat] # Dependency for pdf document generation inkscape imagemagick [platform:dpkg] latexmk [platform:dpkg] texlive-xetex [platform:dpkg] texlive-fonts-recommended [platform:dpkg] texlive [platform:rpm] fonts-liberation [platform:dpkg] liberation-fonts [platform:rpm] librsvg2-bin [platform:dpkg] librsvg2 [platform:rpm] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/devstack/0000775000175000017500000000000000000000000015274 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/devstack/plugin.sh0000664000175000017500000000365500000000000017137 0ustar00zuulzuul00000000000000# plugin.sh - DevStack plugin.sh dispatch script manila-ui function install_manila_ui { # NOTE(vponomaryov): workaround for devstack bug: 1540328 # where devstack install 'test-requirements' but should not do it # for manila-ui project as it installs Horizon from url. # Remove following two 'mv' commands when mentioned bug is fixed. mv $MANILA_UI_DIR/test-requirements.txt $MANILA_UI_DIR/_test-requirements.txt setup_develop ${MANILA_UI_DIR} mv $MANILA_UI_DIR/_test-requirements.txt $MANILA_UI_DIR/test-requirements.txt } # check for service enabled if is_service_enabled horizon && is_service_enabled manila && is_service_enabled manila-ui; then if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then # Set up system services # no-op : elif [[ "$1" == "stack" && "$2" == "install" ]]; then # Perform installation of service source echo_summary "Installing Manila UI" install_manila_ui elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then # Configure after the other layer 1 and 2 services have been configured echo_summary "Configuring Manila UI" cp -a ${MANILA_UI_DIR}/manila_ui/local/enabled/* ${DEST}/horizon/openstack_dashboard/local/enabled/ cp -a ${MANILA_UI_DIR}/manila_ui/local/local_settings.d/* ${DEST}/horizon/openstack_dashboard/local/local_settings.d/ cp -a ${MANILA_UI_DIR}/manila_ui/conf/manila_policy.yaml ${DEST}/horizon/openstack_dashboard/conf/ cp -a ${MANILA_UI_DIR}/manila_ui/conf/default_policies/manila.yaml ${DEST}/horizon/openstack_dashboard/conf/default_policies/ elif [[ "$1" == "stack" && "$2" == "extra" ]]; then # no-op : fi if [[ "$1" == "unstack" ]]; then # no-op : fi if [[ "$1" == "clean" ]]; then # Remove state and transient data # Remember clean.sh first calls unstack.sh # no-op : fi fi ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/devstack/settings0000664000175000017500000000021400000000000017054 0ustar00zuulzuul00000000000000# settings file for manila-ui plugin enable_service manila-ui # set up default directories MANILA_UI_DIR=${MANILA_UI_DIR:=$DEST/manila-ui} ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/0000775000175000017500000000000000000000000014235 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/requirements.txt0000664000175000017500000000062600000000000017525 0ustar00zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. openstackdocstheme>=2.2.1 # Apache-2.0 reno>=3.1.0 # Apache-2.0 doc8>=0.6.0 # Apache-2.0 sphinx>=2.0.0,!=2.1.0 # BSD ddt>=1.0.1 # MIT fixtures>=3.0.0 # Apache-2.0/BSD oslotest>=3.2.0 # Apache-2.0 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/source/0000775000175000017500000000000000000000000015535 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/source/admin/0000775000175000017500000000000000000000000016625 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/admin/index.rst0000664000175000017500000001052200000000000020466 0ustar00zuulzuul00000000000000=================== Administrator Guide =================== Shares are file storage that instances can access. Users can allow or deny a running instance to have access to a share at any time. For information about using the Dashboard to create and manage shares as an end user, see the :doc:`User Guide `. As an administrative user, you can manage shares and share types for users in various projects. You can create and delete share types, and view or delete shares. Create a share type ------------------- #. Log in to the Dashboard and choose the :guilabel:`admin` project from the drop-down list. #. On the :guilabel:`Admin` tab, open the :guilabel:`System` tab and click the :guilabel:`Shares` category. #. Click the :guilabel:`Share Types` tab, and click :guilabel:`Create Share Type` button. In the :guilabel:`Create Share Type` window, enter or select the following values. :guilabel:`Name`: Enter a name for the share type. :guilabel:`Driver handles share servers`: Choose True or False :guilabel:`Extra specs`: To add extra specs, use key=value. #. Click :guilabel:`Create Share Type` button to confirm your changes. .. note:: A message indicates whether the action succeeded. Update share type ----------------- #. Log in to the Dashboard and choose the :guilabel:`admin` project from the drop-down list. #. On the :guilabel:`Admin` tab, open the :guilabel:`System` tab and click the :guilabel:`Shares` category. #. Click the :guilabel:`Share Types` tab, select the share type that you want to update. #. Select :guilabel:`Update Share Type` from Actions. #. In the :guilabel:`Update Share Type` window, update extra specs. :guilabel:`Extra specs`: To add extra specs, use key=value. To unset extra specs, use key. :guilabel:`Name`: To update share type name. :guilabel:`Description`: To update share type description. :guilabel:`Public`: To update share type visibility. #. Click :guilabel:`Update Share Type` button to confirm your changes. .. note:: A message indicates whether the action succeeded. Delete share types ------------------ When you delete a share type, shares of that type are not deleted. #. Log in to the Dashboard and choose the :guilabel:`admin` project from the drop-down list. #. On the :guilabel:`Admin` tab, open the :guilabel:`System` tab and click the :guilabel:`Shares` category. #. Click the :guilabel:`Share Types` tab, select the share type or types that you want to delete. #. Click :guilabel:`Delete Share Types` button. #. In the :guilabel:`Confirm Delete Share Types` window, click the :guilabel:`Delete Share Types` button to confirm the action. .. note:: A message indicates whether the action succeeded. Delete shares ------------- #. Log in to the Dashboard and choose the :guilabel:`admin` project from the drop-down list. #. On the :guilabel:`Admin` tab, open the :guilabel:`System` tab and click the :guilabel:`Shares` category. #. Select the share or shares that you want to delete. #. Click :guilabel:`Delete Shares` button. #. In the :guilabel:`Confirm Delete Shares` window, click the :guilabel:`Delete Shares` button to confirm the action. .. note:: A message indicates whether the action succeeded. Delete share server ------------------- #. Log in to the Dashboard and choose the :guilabel:`admin` project from the drop-down list. #. On the :guilabel:`Admin` tab, open the :guilabel:`System` tab and click the :guilabel:`Share Servers` category. #. Select the share that you want to delete. #. Click :guilabel:`Delete Share Server` button. #. In the :guilabel:`Confirm Delete Share Server` window, click the :guilabel:`Delete Share Server` button to confirm the action. .. note:: A message indicates whether the action succeeded. Delete share networks --------------------- #. Log in to the Dashboard and choose the :guilabel:`admin` project from the drop-down list. #. On the :guilabel:`Admin` tab, open the :guilabel:`System` tab and click the :guilabel:`Share Networks` category. #. Select the share network or share networks that you want to delete. #. Click :guilabel:`Delete Share Networks` button. #. In the :guilabel:`Confirm Delete Share Networks` window, click the :guilabel:`Delete Share Networks` button to confirm the action. .. note:: A message indicates whether the action succeeded. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/conf.py0000664000175000017500000000670000000000000017037 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys sys.path.insert(0, os.path.abspath('../..')) # -- General configuration ---------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', #'sphinx.ext.intersphinx', 'openstackdocstheme', 'sphinx.ext.imgconverter', ] # openstackdocstheme options openstackdocs_repo_name = 'openstack/manila-ui' openstackdocs_pdf_link = True openstackdocs_bug_project = 'manila-ui' openstackdocs_bug_tag = 'docs' # autodoc generation is a bit aggressive and a nuisance when doing heavy # text edit cycles. # execute "export SPHINX_DEBUG=1" in your terminal to disable # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = 'manila-ui' copyright = '2013, OpenStack Foundation' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. # html_theme_path = ["."] html_theme = 'openstackdocs' # html_static_path = ['static'] # Output file base name for HTML help builder. htmlhelp_basename = '%sdoc' % project # Example configuration for intersphinx: refer to the Python standard library. #intersphinx_mapping = {'http://docs.python.org/': None} # -- Options for LaTeX output ------------------------------------------------- # The paper size ('letter' or 'a4'). # latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). # latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass # [howto/manual]). latex_documents = [ ('index', 'doc-%s.tex' % project, '%s Documentation' % project, 'OpenStack Foundation', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # Additional stuff for the LaTeX preamble. # latex_preamble = '' # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_use_modindex = True latex_domain_indices = False latex_elements = { 'makeindex': '', 'printindex': '', 'preamble': r'\setcounter{tocdepth}{3}', 'maxlistdepth': 10, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/source/configuration/0000775000175000017500000000000000000000000020404 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/configuration/index.rst0000664000175000017500000000220500000000000022244 0ustar00zuulzuul00000000000000============= Configuration ============= It is possible to enable or disable some Manila UI features. To do so, look for files located in "manila_ui/local/local_settings.d/" directory, where you can redefine the values of the OPENSTACK_MANILA_FEATURES dict: * enable_share_groups * enable_replication * enable_migration * enable_public_share_type_creation * enable_public_share_group_type_creation * enable_public_shares * enabled_share_protocols By default, enabled_share_protocols within the OPENSTACK_MANILA_FEATURES dict contains a list with all the supported protocols. The operator can change this to display to users only those protocols that has been deployed and are available to use. E.g. if only NFS is available, the operator is expected to redefine enabled_share_protocols as follows: .. code-block:: python OPENSTACK_MANILA_FEATURES = { 'enable_share_groups': True, 'enable_replication': True, 'enable_migration': True, 'enable_public_share_type_creation': True, 'enable_public_share_group_type_creation': True, 'enable_public_shares': True, 'enabled_share_protocols': ['NFS'], } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/source/contributor/0000775000175000017500000000000000000000000020107 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/contributor/adding_release_notes.rst0000664000175000017500000001276200000000000025007 0ustar00zuulzuul00000000000000.. _adding_release_notes: Release Notes ============= What are release notes? ~~~~~~~~~~~~~~~~~~~~~~~ Release notes are important for change management within manila. Since manila follows a release cycle with milestones, release notes provide a way for the community and users to quickly grasp what changes occurred within a development milestone. To the OpenStack release management and documentation teams, release notes are a way to compile changes per milestone. These notes are published on the `OpenStack Releases website `_. Automated tooling is built around ``releasenotes`` and they get appropriately handled per release milestone, including any back-ports to stable releases. What needs a release note? ~~~~~~~~~~~~~~~~~~~~~~~~~~ * Changes that impact an upgrade, most importantly, those that require a deployer to take some action while upgrading * A new feature is implemented * An existing feature is deprecated * An existing feature is removed * Behavior of an existing feature has changed in a discernible way to an end user or administrator * A security bug is fixed * New configuration option is added What does not need a release note? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * A code change that doesn't change the general behavior of any feature such as code refactor or logging changes. * Functional or unit test coverage enhancement * Changes to the content of an error message displayed on the UI * Any change submitted with a justified TrivialFix flag added in the commit message * Adding or changing documentation within in-tree documentation guides How do I add a release note? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We use `Reno `_ to create and manage release notes. The new subcommand combines a random suffix with a "slug" value to make the new file with a unique name that is easy to identify again later. To create a release note for your change, use: .. code-block:: console $ reno new slug-goes-here If reno is not installed globally on your system, you can use a tox environment in manila: .. code-block:: console $ tox -e newnote slug-goes-here .. note:: When you are adding a bug-fix reno, name your file using the template: "bug--slug-goes-here". Then add the notes in ``yaml`` format in the file created. Pay attention to the type of section. The following are general sections to use: prelude General comments about the change. The prelude from all notes in a release are combined, in note order, to produce a single prelude introducing the release. features New features introduced issues A list of known issues with respect to the change being introduced. For example, if the new feature in the change is experimental or known to not work in some cases, it should be mentioned here. upgrade A list of upgrade notes in the release. Any removals that affect upgrades are to be noted here. deprecations Any features, APIs, configuration options that the change has deprecated. Deprecations are not removals. Deprecations suggest that there will be support for a certain timeline. Deprecation should allow time for users to make necessary changes for the removal to happen in a future release. It is important to note the timeline of deprecation in this section. critical A list of *fixed* critical bugs (descriptions only). security A list of *fixed* security issues (descriptions only). fixes A list of other *fixed* bugs (descriptions only). other Other notes that are important but do not fall into any of the given categories. :: --- prelude: > Replace this text with content to appear at the top of the section for this change. features: - List new features here, or remove this section. issues: - List known issues here, or remove this section. upgrade: - List upgrade notes here, or remove this section. deprecations: - List deprecation notes here, or remove this section critical: - Add critical notes here, or remove this section. security: - Add security notes here, or remove this section. fixes: - Add normal bug fixes here, or remove this section. other: - Add other notes here, or remove this section. Dos and Don'ts ~~~~~~~~~~~~~~ * Release notes need to be succinct. Short and unambiguous descriptions are preferred * Write in past tense, unless you are writing an imperative statement * Do not have blank sections in the file * Do not include code or links * Avoid special rst formatting unless absolutely necessary * Always prefer including a release note in the same patch * Release notes are not a replacement for developer/user/admin documentation * Release notes are not a way of conveying behavior of any features or usage of any APIs * Limit a release note to fewer than 2-3 lines per change per section * OpenStack prefers atomic changes. So remember that your change may need the fewest sections possible * General writing guidelines can be found `here `_ * Proofread your note. Pretend you are a user or a deployer who is reading the note after a milestone or a release has been cut Examples ~~~~~~~~ The following need only be considered as directions for formatting. They are **not** fixes or features in manila. * *add-share-network-create-workflows-41cad17c1498a3.yaml* .. code-block:: yaml --- features: - switched share network creation into two-step workflows.././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/contributor/contributing.rst0000664000175000017500000000426400000000000023356 0ustar00zuulzuul00000000000000============================ So You Want to Contribute... ============================ For general information on contributing to OpenStack, please check out the `contributor guide `_ to get started. It covers all the basics that are common to all OpenStack projects: the accounts you need, the basics of interacting with our Gerrit review system, how we communicate as a community, etc. This project contains a plug-in to the OpenStack Dashboard (Horizon). It adds functionality to the OpenStack Dashboard to interact with `Manila `_, the OpenStack Shared File Systems service. Refer to the `Contributor guide for Manila `_ for information regarding the team's task trackers, communicating with other project developers and contacting the core team. See :doc:`development-environment` for details about how to bootstrap a development environment and test manila-ui. Bugs ~~~~ You found an issue and want to make sure we are aware of it? You can do so on `Launchpad `_. If you're looking to contribute, search for the `low-hanging-fruit`_ tag to see issues that are easier to get started with. .. _project-structure: Project Structure ~~~~~~~~~~~~~~~~~ This project includes two dashboard components: - `administrator dashboard`_ - `user dashboard`_ The administrator dashboard extends the OpenStack Dashboard's administrator interface by adding ``Share`` (short for ``Shared File Systems``) functionality to manage Share and Share Group Types, Share servers and other `administrator-only` components of the Shared File System service. It also extends the functionality of the Identity service to allow controlling Shared File System service quotas. The User dashboard provides all user facing functionality. .. _low-hanging-fruit: https://bugs.launchpad.net/manila-ui/+bugs?field.tag=low-hanging-fruit .. _administrator dashboard: https://opendev.org/openstack/manila-ui/src/branch/master/manila_ui/dashboards/admin .. _user dashboard: https://opendev.org/openstack/manila-ui/src/branch/master/manila_ui/dashboards/project ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/contributor/development-environment.rst0000664000175000017500000001345100000000000025531 0ustar00zuulzuul00000000000000.. _development-environment: ==================== Developing manila-ui ==================== For simple documentation and code fixes, you don't need a comprehensive test environment with this project's main dependencies such as manila, python-manilaclient and horizon. Before submitting any code fixes for review, you can run :ref:`unit-tests` locally. To try your changes with manila-ui and Horizon and all other dependencies, we recommend the use of DevStack. DevStack -------- DevStack can help you setup a simple development environment for developing and testing manila-ui. Read the section about DevStack in the `manila contributor guide`_. .. note:: We absolutely recommend using a ``fake shared file system back end`` as opposed to a real storage system to experience the full capabilities of manila UI. Manila UI is built with the assumption that all APIs manila exposes are usable. In reality, different real world storage back ends have `different capabilities`_ and this project doesn't need to worry about them to provide a general purpose graphical user interface to Manila. A fake driver provides fake storage, so don't expect to be able to mount or use the shared file systems that you create with it. You can use the following local.conf file to configure DevStack including Manila and manila-ui using a few fake back ends: .. code-block:: console [[local|localrc]] # auth ADMIN_PASSWORD=nomoresecret DATABASE_PASSWORD=$ADMIN_PASSWORD RABBIT_PASSWORD=$ADMIN_PASSWORD SERVICE_PASSWORD=$ADMIN_PASSWORD # enable logging for DevStack LOGFILE=/opt/stack/logs/stack.sh.log # Logging mode for DevStack services VERBOSE=True # manila enable_plugin manila https://opendev.org/openstack/manila # manila-ui enable_plugin manila-ui https://opendev.org/openstack/manila-ui # python-manilaclient LIBS_FROM_GIT=python-manilaclient # share driver SHARE_DRIVER=manila.tests.share.drivers.dummy.DummyDriver # share types MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS='snapshot_support=True create_share_from_snapshot_support=True revert_to_snapshot_support=True mount_snapshot_support=True' MANILA_CONFIGURE_DEFAULT_TYPES=True # backends and groups MANILA_ENABLED_BACKENDS=alpha,beta,gamma,delta MANILA_CONFIGURE_GROUPS=alpha,beta,gamma,delta,membernet,adminnet # alpha MANILA_OPTGROUP_alpha_share_driver=manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_alpha_driver_handles_share_servers=True MANILA_OPTGROUP_alpha_share_backend_name=ALPHA MANILA_OPTGROUP_alpha_network_config_group=membernet MANILA_OPTGROUP_alpha_admin_network_config_group=adminnet # beta MANILA_OPTGROUP_beta_share_driver=manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_beta_driver_handles_share_servers=True MANILA_OPTGROUP_beta_share_backend_name=BETA MANILA_OPTGROUP_beta_network_config_group=membernet MANILA_OPTGROUP_beta_admin_network_config_group=adminnet # gamma MANILA_OPTGROUP_gamma_share_driver=manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_gamma_driver_handles_share_servers=False MANILA_OPTGROUP_gamma_share_backend_name=GAMMA MANILA_OPTGROUP_gamma_replication_domain=DUMMY_DOMAIN # delta MANILA_OPTGROUP_delta_share_driver=manila.tests.share.drivers.dummy.DummyDriver MANILA_OPTGROUP_delta_driver_handles_share_servers=False MANILA_OPTGROUP_delta_share_backend_name=DELTA MANILA_OPTGROUP_delta_replication_domain=DUMMY_DOMAIN # membernet MANILA_OPTGROUP_membernet_network_api_class=manila.network.standalone_network_plugin.StandaloneNetworkPlugin MANILA_OPTGROUP_membernet_standalone_network_plugin_gateway=10.0.0.1 MANILA_OPTGROUP_membernet_standalone_network_plugin_mask=24 MANILA_OPTGROUP_membernet_standalone_network_plugin_network_type=vlan MANILA_OPTGROUP_membernet_standalone_network_plugin_segmentation_id=1010 MANILA_OPTGROUP_membernet_standalone_network_plugin_allowed_ip_ranges=10.0.0.10-10.0.0.209 MANILA_OPTGROUP_membernet_network_plugin_ipv4_enabled=True # adminnet MANILA_OPTGROUP_adminnet_network_api_class=manila.network.standalone_network_plugin.StandaloneNetworkPlugin MANILA_OPTGROUP_adminnet_standalone_network_plugin_gateway=11.0.0.1 MANILA_OPTGROUP_adminnet_standalone_network_plugin_mask=24 MANILA_OPTGROUP_adminnet_standalone_network_plugin_network_type=vlan MANILA_OPTGROUP_adminnet_standalone_network_plugin_segmentation_id=1011 MANILA_OPTGROUP_adminnet_standalone_network_plugin_allowed_ip_ranges=11.0.0.10-11.0.0.19,11.0.0.30-11.0.0.39,11.0.0.50-11.0.0.199 MANILA_OPTGROUP_adminnet_network_plugin_ipv4_enabled=True Once your DevStack is ready, you can log into the OpenStack Dashboard and explore the ``Share`` dashboards under `Project` and `Admin` sections that are included due to manila-ui. See the `Horizon user guide`_ for instructions regarding logging into the OpenStack Dashboard. .. _unit-tests: Running unit tests ------------------ The unit tests can be executed directly from within this Manila UI plugin project directory by using:: $ cd ../manila-ui $ tox This is made possible by the dependency in test-requirements.txt upon the horizon source, which pulls down all of the horizon and openstack_dashboard modules that the plugin uses. To run only py3 unit tests, use following command:: $ tox -e py3 To run unit tests using specific Django version use the following:: $ tox -e py3-dj22 $ tox -e py3-dj110 .. _manila contributor guide: https://docs.openstack.org/manila/latest/contributor/development-environment-devstack.html .. _different capabilities: https://docs.openstack.org/manila/latest/admin/share_back_ends_feature_support_mapping.html .. _Horizon user guide: https://docs.openstack.org/horizon/latest/user/log-in.html ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/contributor/features.rst0000664000175000017500000000212400000000000022456 0ustar00zuulzuul00000000000000=================== Adding New Features =================== When implementing a new feature, you may think about making it optional, so it could be enabled or disabled in different deployments. How to use it: .. code-block:: python from django.conf import settings manila_config = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) manila_config.get('your_new_config_option', 'value_of_config_option') See :doc:`/configuration/index` section for more configuration details. It is also expected that each addition of new logic to Manila UI is covered by unit tests. Test modules should be located under "manila_ui/tests", satisfying the following template when tests are written for a specific module: .. code-block:: none manila_ui[/tests]/path/to/[test_]modulename.py However, when testing the flow between different modules (using test app), the tests can be added to a test module that can satisfy the following template: .. code-block:: none manila_ui/tests/path/to/directory/tests.py Manila UI tests use the ``mock`` module from the ``unittest`` package for unit testing. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/contributor/index.rst0000664000175000017500000000043600000000000021753 0ustar00zuulzuul00000000000000========================= Contributor Documentation ========================= .. toctree:: :maxdepth: 3 contributing development-environment features Programming HowTos and Tutorials -------------------------------- .. toctree:: :maxdepth: 3 adding_release_notes././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/index.rst0000664000175000017500000000204000000000000017372 0ustar00zuulzuul00000000000000.. 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. ======================================= manila-ui - Manila Management Dashboard ======================================= .. toctree:: :maxdepth: 2 install/installation .. toctree:: :maxdepth: 2 configuration/index .. toctree:: :maxdepth: 1 user/index .. toctree:: :maxdepth: 1 admin/index .. toctree:: :maxdepth: 2 contributor/index .. only:: html Indices and tables ------------------ * :ref:`genindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/source/install/0000775000175000017500000000000000000000000017203 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/install/installation.rst0000664000175000017500000000223700000000000022442 0ustar00zuulzuul00000000000000============ Installation ============ Manual Installation ------------------- Begin by installing Horizon following the `Horizon Manual Installation Guide `__ and clone Manila UI repository:: git clone https://opendev.org/openstack/manila-ui Install Manila UI with all dependencies. From within the horizon folder:: pip install -e ../manila-ui/ And enable it in Horizon.:: cp ../manila-ui/manila_ui/local/enabled/_*.py openstack_dashboard/local/enabled cp ../manila-ui/manila_ui/local/local_settings.d/_90_manila_*.py openstack_dashboard/local/local_settings.d .. _install-rdo: Installing Manila UI in RDO --------------------------- In order to install Manila UI in `RDO `__, please follow the steps below (you may need to use `sudo` privileges if you are not root):: # yum install -y openstack-manila-ui # systemctl restart httpd # systemctl restart memcached Manila UI will now be available through OpenStack Horizon; look for the Shares tab under Project > Share. You can access Horizon with Manila UI using the same URL and port as before. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7866514 manila-ui-11.0.0/doc/source/user/0000775000175000017500000000000000000000000016513 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/doc/source/user/index.rst0000664000175000017500000001651300000000000020362 0ustar00zuulzuul00000000000000========== User Guide ========== Shares are file storage that you provide access to instances. You can allow access to a share to a running instance or deny access to a share and allow access to it to another instance at any time. You can also delete a share. You can create snapshot from a share if the driver supports it. Only administrative users can create share types. Create a share -------------- #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Click :guilabel:`Create Share`. In the dialog box that opens, enter or select the following values. :guilabel:`Share Name`: Specify a name for the share. :guilabel:`Description`: Optionally, provide a brief description for the share. :guilabel:`Share Type`: Choose a share type. :guilabel:`Size (GB)`: The size of the share in gibibytes (GiB). :guilabel:`Share Protocol`: Select NFS, CIFS, GlusterFS, or HDFS. :guilabel:`Share Network`: Choose a share network. :guilabel:`Metadata`: Enter metadata for the share creation if needed. #. Click :guilabel:`Create Share`. The dashboard shows the share on the :guilabel:`Shares` tab. Delete a share -------------- #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Select the check boxes for the shares that you want to delete. #. Click :guilabel:`Delete Shares` and confirm your choice. A message indicates whether the action was successful. Allow access ------------ #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Go to the share that you want to allow access and choose :guilabel:`Manage Rules` from Actions. #. Click :guilabel:`Add rule`. :guilabel:`Access Type`: Choose ip, user, or cert. :guilabel:`Access Level`: Choose read-write or read-only. :guilabel:`Access To`: Fill in Access To field. #. Click :guilabel:`Add Rule`. A message indicates whether the action was successful. Deny access ----------- #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Go to the share that you want to deny access and choose :guilabel:`Manage Rules` from Actions. #. Choose the rule you want to delete. #. Click :guilabel:`Delete rule` and confirm your choice. A message indicates whether the action was successful. Edit share access metadata -------------------------- #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Go to the share that you want to deny access and choose :guilabel:`Manage Rules` from Actions. #. Choose the rule you want to edit. #. Click :guilabel:`Edit Rule Metadata`: To add share access metadata, use key=value. To unset metadata, use key. A message indicates whether the action was successful. Edit share metadata ------------------- #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Go to the share that you want to edit and choose :guilabel:`Edit Share Metadata` from Actions. #. :guilabel:`Metadata`: To add share metadata, use key=value. To unset metadata, use key. #. Click :guilabel:`Edit Share Metadata`. A message indicates whether the action was successful. Edit share ---------- #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Go to the share that you want to edit and choose :guilabel:`Edit Share` from Actions. #. :guilabel:`Share Name`: Enter a new share name. #. :guilabel:`Description`: Enter a new description. #. Click :guilabel:`Edit Share`. A message indicates whether the action was successful. Resize share ------------ #. Log in to the dashboard, choose a project, and click :guilabel:`Shares`. #. Go to the share that you want to edit and choose :guilabel:`Resize Share` from Actions. #. :guilabel:`New Size (GB)`: Enter new size. It can be increased or decreased from the original size. The size of the share cannot be lower than the size of the data stored in the share. If increased, the size of the share will be extended. If decreased, the size of the share will be shrinked. #. Click :guilabel:`Resize Share`. A message indicates whether the action was successful. Create share network -------------------- #. Log in to the dashboard, choose a project, click :guilabel:`Shares`, and click :guilabel:`Share Networks`. #. Click :guilabel:`Create Share Network`. In the dialog box that opens, enter or select the following values. :guilabel:`Name`: Specify a name for the share network. :guilabel:`Description`: Optionally, provide a brief description for the share network. :guilabel:`Neutron Net`: Choose a neutron network. :guilabel:`Neutron Subnet`: Choose a neutron subnet. #. Click :guilabel:`Create Share Network`. The dashboard shows the share network on the :guilabel:`Share Networks` tab. Delete a share network ---------------------- #. Log in to the dashboard, choose a project, click :guilabel:`Shares`, and click :guilabel:`Share Networks`. #. Select the check boxes for the share networks that you want to delete. #. Click :guilabel:`Delete Share Networks` and confirm your choice. A message indicates whether the action was successful. Edit share network ------------------ #. Log in to the dashboard, choose a project, click :guilabel:`Shares`, and click :guilabel:`Share Networks`. #. Go to the share network that you want to edit and choose :guilabel:`Edit Share Network` from Actions. #. :guilabel:`Name`: Enter a new share network name. #. :guilabel:`Description`: Enter a new description. #. Click :guilabel:`Edit Share Network`. A message indicates whether the action was successful. Create security service ----------------------- #. Log in to the dashboard, choose a project, click :guilabel:`Shares`, and click :guilabel:`Security Services`. #. Click :guilabel:`Create Security Service`. In the dialog box that opens, enter or select the following values. :guilabel:`Name`: Specify a name for the security service. :guilabel:`DNS IP`: Enter the DNS IP address. :guilabel:`Server`: Enter the server name. :guilabel:`Domain`: Enter the domain name. :guilabel:`User`: Enter the user name. :guilabel:`Password`: Enter the password. :guilabel:`Confirm Password`: Enter the password again to confirm. :guilabel:`Type`: Choose the type from Active Directory, LDAP, or Kerberos. :guilabel:`Description`: Optionally, provide a brief description for the security service. #. Click :guilabel:`Create Security Service`. The dashboard shows the security service on the :guilabel:`Security Services` tab. Delete a security service ------------------------- #. Log in to the dashboard, choose a project, click :guilabel:`Shares`, and click :guilabel:`Security Services`. #. Select the check boxes for the security services that you want to delete. #. Click :guilabel:`Delete Security Services` and confirm your choice. A message indicates whether the action was successful. Edit security service --------------------- #. Log in to the dashboard, choose a project, click :guilabel:`Shares`, and click :guilabel:`Security Services`. #. Go to the security service that you want to edit and choose :guilabel:`Edit Security Service` from Actions. #. :guilabel:`Name`: Enter a new security service name. #. :guilabel:`Description`: Enter a new description. #. Click :guilabel:`Edit Security Service`. A message indicates whether the action was successful. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manage.py0000775000175000017500000000147300000000000015302 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import sys from django.core.management import execute_from_command_line if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manila_ui.tests.settings") execute_from_command_line(sys.argv) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/0000775000175000017500000000000000000000000015426 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/__init__.py0000664000175000017500000000123100000000000017534 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # 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 pbr.version __version__ = pbr.version.VersionInfo( 'manila_ui').version_string() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/api/0000775000175000017500000000000000000000000016177 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/api/__init__.py0000664000175000017500000000000000000000000020276 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/api/manila.py0000664000175000017500000005446400000000000020027 0ustar00zuulzuul00000000000000# Copyright 2012 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Copyright 2012 OpenStack Foundation # Copyright 2012 Nebula, Inc. # Copyright (c) 2012 X.commerce, a business unit of eBay Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.conf import settings from horizon import exceptions import logging from openstack_dashboard.api import base from manilaclient import client as manila_client LOG = logging.getLogger(__name__) MANILA_UI_USER_AGENT_REPR = "manila_ui_plugin_for_horizon" MANILA_VERSION = "2.51" MANILA_SERVICE_TYPE = "sharev2" # API static values SHARE_STATE_AVAILABLE = "available" DEFAULT_QUOTA_NAME = 'default' MANILA_QUOTA_FIELDS = { "shares", "share_gigabytes", "share_snapshots", "share_snapshot_gigabytes", "share_networks", "share_groups", "share_group_snapshots", } # UI field names do not match data field names returned, have # a map to convert them. MANILA_QUOTA_FIELDS_DATA_MAP = { "shares": "shares", "share_gigabytes": "gigabytes", "share_snapshots": "snapshots", "share_snapshot_gigabytes": "snapshot_gigabytes", "share_networks": "share_networks", "share_groups": "share_groups", "share_group_snapshots": "share_group_snapshots", } def manilaclient(request): insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None) manila_url = "" try: manila_url = base.url_for(request, MANILA_SERVICE_TYPE) except exceptions.ServiceCatalogException: LOG.debug('no share service configured.') return None LOG.debug('manilaclient connection created using token "%s" and url "%s"' % (request.user.token.id, manila_url)) c = manila_client.Client( MANILA_VERSION, username=request.user.username, input_auth_token=request.user.token.id, project_id=request.user.tenant_id, service_catalog_url=manila_url, insecure=insecure, cacert=cacert, http_log_debug=settings.DEBUG, user_agent=MANILA_UI_USER_AGENT_REPR, ) c.client.auth_token = request.user.token.id c.client.management_url = manila_url return c def share_list(request, search_opts=None): search_opts = search_opts or {} return manilaclient(request).shares.list(search_opts=search_opts) def share_get(request, share_id): share_data = manilaclient(request).shares.get(share_id) return share_data def share_create(request, size, name, description, proto, snapshot_id=None, metadata=None, share_network=None, share_type=None, is_public=None, availability_zone=None, share_group_id=None): return manilaclient(request).shares.create( proto, size, name=name, description=description, share_network=share_network, snapshot_id=snapshot_id, metadata=metadata, share_type=share_type, is_public=is_public, availability_zone=availability_zone, share_group_id=share_group_id, ) def share_delete(request, share_id, share_group_id=None): return manilaclient(request).shares.delete( share_id, share_group_id=share_group_id, ) def share_update(request, share_id, name, description, is_public=False): share_data = { 'display_name': name, 'display_description': description, 'is_public': is_public } return manilaclient(request).shares.update(share_id, **share_data) def share_rules_list(request, share_id): return manilaclient(request).share_access_rules.access_list(share_id) def share_rule_get(request, rule_id): return manilaclient(request).share_access_rules.get(rule_id) def share_rule_set_metadata(request, rule, metadata): return manilaclient(request).share_access_rules.set_metadata( rule, metadata) def share_rule_unset_metadata(request, rule, keys): return manilaclient(request).share_access_rules.unset_metadata( rule, keys) def share_export_location_list(request, share_id): return manilaclient(request).share_export_locations.list(share_id) def share_instance_export_location_list(request, share_instance_id): return manilaclient(request).share_instance_export_locations.list( share_instance_id) def share_allow(request, share_id, access_type, access_to, access_level, metadata=None): return manilaclient(request).shares.allow( share_id, access_type, access_to, access_level, metadata) def share_deny(request, share_id, rule_id): return manilaclient(request).shares.deny(share_id, rule_id) def share_manage(request, service_host, protocol, export_path, driver_options=None, share_type=None, name=None, description=None, is_public=False): return manilaclient(request).shares.manage( service_host=service_host, protocol=protocol, export_path=export_path, driver_options=driver_options, share_type=share_type, name=name, description=description, is_public=is_public, ) def migration_start(request, share, dest_host, force_host_assisted_migration, writable, preserve_metadata, preserve_snapshots, nondisruptive, new_share_network_id, new_share_type_id): return manilaclient(request).shares.migration_start( share, host=dest_host, force_host_assisted_migration=force_host_assisted_migration, writable=writable, preserve_metadata=preserve_metadata, preserve_snapshots=preserve_snapshots, nondisruptive=nondisruptive, new_share_network_id=new_share_network_id, new_share_type_id=new_share_type_id ) def migration_complete(request, share): return manilaclient(request).shares.migration_complete(share) def migration_get_progress(request, share): return manilaclient(request).shares.migration_get_progress(share) def migration_cancel(request, share): return manilaclient(request).shares.migration_cancel(share) def share_unmanage(request, share): # Param 'share' can be either string with ID or object with attr 'id'. return manilaclient(request).shares.unmanage(share) def share_resize(request, share_id, new_size, orig_size): if orig_size > new_size: return manilaclient(request).shares.shrink(share_id, new_size) else: return manilaclient(request).shares.extend(share_id, new_size) def share_revert(request, share, snapshot): """Sends request to revert share to specific snapshot. This API available only since 2.27 microversion. :param share: Share class instance or share ID :param snapshot: ShareSnapshot class instance or share snapshot ID """ return manilaclient(request).shares.revert_to_snapshot(share, snapshot) def share_snapshot_get(request, snapshot_id): return manilaclient(request).share_snapshots.get(snapshot_id) def share_snapshot_update(request, snapshot_id, name, description): snapshot_data = {'display_name': name, 'display_description': description} return manilaclient(request).share_snapshots.update( snapshot_id, **snapshot_data) def share_snapshot_list(request, detailed=True, search_opts=None, sort_key=None, sort_dir=None): # Example of 'search_opts' value: # {'share_id': 'id_of_existing_share'} return manilaclient(request).share_snapshots.list( detailed=detailed, search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir, ) def share_snapshot_create(request, share_id, name=None, description=None, force=False): return manilaclient(request).share_snapshots.create( share_id, force=force, name=name, description=description) def share_snapshot_delete(request, snapshot_id): return manilaclient(request).share_snapshots.delete(snapshot_id) def share_snapshot_allow(request, snapshot_id, access_type, access_to): return manilaclient(request).share_snapshots.allow( snapshot_id, access_type, access_to) def share_snapshot_deny(request, snapshot_id, rule_id): return manilaclient(request).share_snapshots.deny(snapshot_id, rule_id) def share_snapshot_rules_list(request, snapshot_id): return manilaclient(request).share_snapshots.access_list(snapshot_id) def share_snap_export_location_list(request, snapshot): return manilaclient(request).share_snapshot_export_locations.list( snapshot=snapshot) def share_snap_instance_export_location_list(request, snapshot_instance): return manilaclient(request).share_snapshot_export_locations.list( snapshot_instance=snapshot_instance) def share_server_list(request, search_opts=None): return manilaclient(request).share_servers.list(search_opts=search_opts) def share_server_get(request, share_serv_id): return manilaclient(request).share_servers.get(share_serv_id) def share_server_delete(request, share_serv_id): return manilaclient(request).share_servers.delete(share_serv_id) def share_network_list(request, detailed=False, search_opts=None): return manilaclient(request).share_networks.list(detailed=detailed, search_opts=search_opts) def share_network_create(request, neutron_net_id=None, neutron_subnet_id=None, name=None, description=None, availability_zone=None): return manilaclient(request).share_networks.create( neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id, name=name, description=description, availability_zone=availability_zone) def share_network_get(request, share_net_id): return manilaclient(request).share_networks.get(share_net_id) def share_network_update(request, share_net_id, name=None, description=None): return manilaclient(request).share_networks.update( share_net_id, name=name, description=description) def share_network_delete(request, share_network_id): return manilaclient(request).share_networks.delete(share_network_id) def security_service_list(request, search_opts=None): return manilaclient(request).security_services.list( detailed=True, search_opts=search_opts) def security_service_get(request, sec_service_id, search_opts=None): return manilaclient(request).security_services.get(sec_service_id) def security_service_create(request, type, dns_ip=None, ou=None, server=None, domain=None, user=None, password=None, name=None, description=None): return manilaclient(request).security_services.create( type, dns_ip=dns_ip, ou=ou, server=server, domain=domain, user=user, password=password, name=name, description=description) def security_service_update(request, security_service_id, dns_ip=None, ou=None, server=None, domain=None, password=None, user=None, name=None, description=None): return manilaclient(request).security_services.update( security_service_id, dns_ip=dns_ip, ou=ou, server=server, domain=domain, password=password, user=user, name=name, description=description) def security_service_delete(request, security_service_id): return manilaclient(request).security_services.delete(security_service_id) def share_network_security_service_add(request, share_network_id, security_service_id): return manilaclient(request).share_networks.add_security_service( share_network_id, security_service_id) def share_network_security_service_remove(request, share_network_id, security_service_id): return manilaclient(request).share_networks.remove_security_service( share_network_id, security_service_id) def share_network_security_service_list(request, share_network_id): return manilaclient(request).security_services.list( search_opts={'share_network_id': share_network_id}) def share_set_metadata(request, share_id, metadata): return manilaclient(request).shares.set_metadata(share_id, metadata) def share_delete_metadata(request, share_id, keys): return manilaclient(request).shares.delete_metadata(share_id, keys) def tenant_quota_get(request, tenant_id): return base.QuotaSet(manilaclient(request).quotas.get(tenant_id)) def _map_quota_names_for_update(data): mapping = { 'share_gigabytes': 'gigabytes', 'share_snapshots': 'snapshots', 'share_snapshot_gigabytes': 'snapshot_gigabytes', } for k, v in mapping.items(): if k in data: data[v] = data.pop(k) return data def tenant_quota_update(request, tenant_id, **kwargs): _map_quota_names_for_update(kwargs) return manilaclient(request).quotas.update(tenant_id, **kwargs) def default_quota_get(request, tenant_id): return base.QuotaSet(manilaclient(request).quotas.defaults(tenant_id)) def default_quota_update(request, **kwargs): _map_quota_names_for_update(kwargs) manilaclient(request).quota_classes.update(DEFAULT_QUOTA_NAME, **kwargs) def share_type_list(request): return manilaclient(request).share_types.list() def share_type_get(request, share_type_id): return manilaclient(request).share_types.get(share_type_id) def share_type_create(request, name, spec_driver_handles_share_servers, description=None, is_public=True): return manilaclient(request).share_types.create( name=name, description=description, spec_driver_handles_share_servers=spec_driver_handles_share_servers, is_public=is_public) def share_type_update(request, share_type_id, name=None, description=None, is_public=None): share_type_data = { 'name': name, 'description': description, 'is_public': is_public } return manilaclient(request).share_types.get( share_type_id).update(**share_type_data) def share_type_delete(request, share_type_id): return manilaclient(request).share_types.delete(share_type_id) def share_type_get_extra_specs(request, share_type_id): return manilaclient(request).share_types.get(share_type_id).get_keys() def share_type_set_extra_specs(request, share_type_id, extra_specs): return manilaclient(request).share_types.get( share_type_id).set_keys(extra_specs) def share_type_unset_extra_specs(request, share_type_id, keys): return manilaclient(request).share_types.get( share_type_id).unset_keys(keys) def share_type_access_list(request, share_type_id): return manilaclient(request).share_type_access.list(share_type_id) def share_type_access_add(request, share_type_id, project_id): return manilaclient(request).share_type_access.add_project_access( share_type_id, project_id) def share_type_access_remove(request, share_type_id, project_id): return manilaclient(request).share_type_access.remove_project_access( share_type_id, project_id) def share_replica_list(request, share=None): return manilaclient(request).share_replicas.list(share) def share_replica_create(request, share, availability_zone): return manilaclient(request).share_replicas.create( share, availability_zone=availability_zone) def share_replica_get(request, replica): return manilaclient(request).share_replicas.get(replica) def share_replica_delete(request, replica): return manilaclient(request).share_replicas.delete(replica) def share_replica_promote(request, replica): return manilaclient(request).share_replicas.promote(replica) def share_replica_reset_status(request, replica, status): return manilaclient(request).share_replicas.reset_state( replica, status) def share_replica_reset_state(request, replica, state): return manilaclient(request).share_replicas.reset_replica_state( replica, state) def share_replica_resync(request, replica): return manilaclient(request).share_replicas.resync(replica) def tenant_absolute_limits(request): limits = manilaclient(request).limits.get().absolute limits_dict = {} for limit in limits: # -1 is used to represent unlimited quotas if limit.value == -1: limits_dict[limit.name] = float("inf") else: limits_dict[limit.name] = limit.value return limits_dict def share_instance_list(request): return manilaclient(request).share_instances.list() def share_instance_get(request, share_instance_id): return manilaclient(request).share_instances.get(share_instance_id) def availability_zone_list(request): return manilaclient(request).availability_zones.list() def pool_list(request, detailed=False): return manilaclient(request).pools.list(detailed=detailed) # ####### Share Groups # ####### def share_group_create(request, name, description=None, share_group_type=None, share_types=None, share_network=None, source_share_group_snapshot=None, availability_zone=None): return manilaclient(request).share_groups.create( name=name, description=description, share_group_type=share_group_type, share_types=share_types, share_network=share_network, source_share_group_snapshot=source_share_group_snapshot, availability_zone=availability_zone, ) def share_group_get(request, share_group): return manilaclient(request).share_groups.get(share_group) def share_group_update(request, share_group, name, description): return manilaclient(request).share_groups.update( share_group, name=name, description=description, ) def share_group_delete(request, share_group, force=False): return manilaclient(request).share_groups.delete(share_group, force=force) def share_group_reset_state(request, share_group, state): return manilaclient(request).share_groups.reset_state(share_group, state) def share_group_list(request, detailed=True, search_opts=None, sort_key=None, sort_dir=None): return manilaclient(request).share_groups.list( detailed=detailed, search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir, ) # ####### Share Group Snapshots # ####### def share_group_snapshot_create(request, share_group, name, description=None): return manilaclient(request).share_group_snapshots.create( share_group=share_group, name=name, description=description, ) def share_group_snapshot_get(request, share_group_snapshot): return manilaclient(request).share_group_snapshots.get( share_group_snapshot) def share_group_snapshot_update(request, share_group_snapshot, name, description): return manilaclient(request).share_group_snapshots.update( share_group_snapshot, name=name, description=description, ) def share_group_snapshot_delete(request, share_group_snapshot, force=False): return manilaclient(request).share_group_snapshots.delete( share_group_snapshot, force=force) def share_group_snapshot_reset_state(request, share_group_snapshot, state): return manilaclient(request).share_group_snapshots.reset_state( share_group_snapshot, state) def share_group_snapshot_list(request, detailed=True, search_opts=None, sort_key=None, sort_dir=None): return manilaclient(request).share_group_snapshots.list( detailed=detailed, search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir, ) # ####### Share Group Types # ######## def share_group_type_create(request, name, share_types, is_public=False, group_specs=None): return manilaclient(request).share_group_types.create( name=name, share_types=share_types, is_public=is_public, group_specs=group_specs) def share_group_type_get(request, share_group_type): return manilaclient(request).share_group_types.get(share_group_type) def share_group_type_list(request, show_all=True): return manilaclient(request).share_group_types.list(show_all=show_all) def share_group_type_delete(request, share_group_type): return manilaclient(request).share_group_types.delete(share_group_type) def share_group_type_access_list(request, share_group_type): return manilaclient(request).share_group_type_access.list(share_group_type) def share_group_type_access_add(request, share_group_type, project): return manilaclient(request).share_group_type_access.add_project_access( share_group_type, project) def share_group_type_access_remove(request, share_group_type, project): return manilaclient(request).share_group_type_access.remove_project_access( share_group_type, project) def share_group_type_set_specs(request, share_group_type, group_specs): return manilaclient(request).share_group_types.get( share_group_type).set_keys(group_specs) def share_group_type_unset_specs(request, share_group_type, keys): return manilaclient(request).share_group_types.get( share_group_type).unset_keys(keys) def share_group_type_get_specs(request, share_group_type): return manilaclient(request).share_group_types.get( share_group_type).get_keys() # ####### User Messages # ######## def messages_get(request, message_id): return manilaclient(request).messages.get(message_id) def messages_list(request, search_opts=None, sort_key=None, sort_dir=None): return manilaclient(request).messages.list(search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir) def messages_delete(request, message_id): return manilaclient(request).messages.delete(message_id) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/conf/0000775000175000017500000000000000000000000016353 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/conf/default_policies/0000775000175000017500000000000000000000000021666 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/conf/default_policies/manila.yaml0000664000175000017500000017534500000000000024032 0ustar00zuulzuul00000000000000- check_str: role:admin and system_scope:all description: null name: system-admin operations: [] scope_types: - system - check_str: role:member and system_scope:all description: null name: system-member operations: [] scope_types: - system - check_str: role:reader and system_scope:all description: null name: system-reader operations: [] scope_types: - system - check_str: role:admin and project_id:%(project_id)s description: null name: project-admin operations: [] scope_types: - project - check_str: role:member and project_id:%(project_id)s description: null name: project-member operations: [] scope_types: - project - check_str: role:reader and project_id:%(project_id)s description: null name: project-reader operations: [] scope_types: - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: role:admin name: context_is_admin deprecated_since: null description: null name: context_is_admin operations: [] scope_types: - system - check_str: is_admin:True or project_id:%(project_id)s description: null name: admin_or_owner operations: [] scope_types: null - check_str: rule:admin_or_owner description: null name: default operations: [] scope_types: null - check_str: is_admin:True description: null name: admin_api operations: [] scope_types: null - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: availability_zone:index deprecated_since: null description: Get all storage availability zones. name: availability_zone:index operations: - method: GET path: /os-availability-zone - method: GET path: /availability-zone scope_types: - system - project - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: scheduler_stats:pools:index deprecated_since: null description: Get information regarding backends (and storage pools) known to the scheduler. name: scheduler_stats:pools:index operations: - method: GET path: /scheduler-stats/pools - method: GET path: /scheduler-stats/pools?{query} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: scheduler_stats:pools:detail deprecated_since: null description: Get detailed information regarding backends (and storage pools) known to the scheduler. name: scheduler_stats:pools:detail operations: - method: GET path: /scheduler-stats/pools/detail?{query} - method: GET path: /scheduler-stats/pools/detail scope_types: - system - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: '' name: share:create deprecated_since: null description: Create share. name: share:create operations: - method: POST path: /shares scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:create_public_share deprecated_since: null description: Create shares visible across all projects in the cloud. name: share:create_public_share operations: - method: POST path: /shares scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:get deprecated_since: null description: Get share. name: share:get operations: - method: GET path: /shares/{share_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:get_all deprecated_since: null description: List shares. name: share:get_all operations: - method: GET path: /shares - method: GET path: /shares/detail scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:update deprecated_since: null description: Update share. name: share:update operations: - method: PUT path: /shares scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:set_public_share deprecated_since: null description: Update shares to be visible across all projects in the cloud. name: share:set_public_share operations: - method: PUT path: /shares scope_types: - system - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:delete deprecated_since: null description: Delete share. name: share:delete operations: - method: DELETE path: /shares/{share_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:force_delete deprecated_since: null description: Force Delete a share. name: share:force_delete operations: - method: DELETE path: /shares/{share_id} scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:manage deprecated_since: null description: Manage share. name: share:manage operations: - method: POST path: /shares/manage scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:unmanage deprecated_since: null description: Unmanage share. name: share:unmanage operations: - method: POST path: /shares/unmanage scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:list_by_host deprecated_since: null description: List share by host. name: share:list_by_host operations: - method: GET path: /shares - method: GET path: /shares/detail scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:list_by_share_server_id deprecated_since: null description: List share by server id. name: share:list_by_share_server_id operations: - method: GET path: /shares - method: GET path: /shares/detail scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:access_get deprecated_since: null description: Get share access rule, it under deny access operation. name: share:access_get operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:access_get_all deprecated_since: null description: List share access rules. name: share:access_get_all operations: - method: GET path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:extend deprecated_since: null description: Extend share. name: share:extend operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:shrink deprecated_since: null description: Shrink share. name: share:shrink operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:migration_start deprecated_since: null description: Migrate a share to the specified host. name: share:migration_start operations: - method: POST path: /shares/{share_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:migration_complete deprecated_since: null description: Invokes 2nd phase of share migration. name: share:migration_complete operations: - method: POST path: /shares/{share_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:migration_cancel deprecated_since: null description: Attempts to cancel share migration. name: share:migration_cancel operations: - method: POST path: /shares/{share_id}/action scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:migration_get_progress deprecated_since: null description: Retrieve share migration progress for a given share. name: share:migration_get_progress operations: - method: POST path: /shares/{share_id}/action scope_types: - system - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:reset_task_state deprecated_since: null description: Reset task state. name: share:reset_task_state operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share:reset_status deprecated_since: null description: Reset status. name: share:reset_status operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:revert_to_snapshot deprecated_since: null description: Revert a share to a snapshot. name: share:revert_to_snapshot operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:allow_access deprecated_since: null description: Add share access rule. name: share:allow_access operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:deny_access deprecated_since: null description: Remove share access rule. name: share:deny_access operations: - method: POST path: /shares/{share_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:update_share_metadata deprecated_since: null description: Update share metadata. name: share:update_share_metadata operations: - method: PUT path: /shares/{share_id}/metadata scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:delete_share_metadata deprecated_since: null description: Delete share metadata. name: share:delete_share_metadata operations: - method: DELETE path: /shares/{share_id}/metadata/{key} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:get_share_metadata deprecated_since: null description: Get share metadata. name: share:get_share_metadata operations: - method: GET path: /shares/{share_id}/metadata scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:create_snapshot deprecated_since: null description: Create share snapshot. name: share:create_snapshot operations: - method: POST path: /snapshots scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:delete_snapshot deprecated_since: null description: Delete share snapshot. name: share:delete_snapshot operations: - method: DELETE path: /snapshots/{snapshot_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share:snapshot_update deprecated_since: null description: Update share snapshot. name: share:snapshot_update operations: - method: PUT path: /snapshots/{snapshot_id}/action scope_types: - system - project - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_instance_export_location:index deprecated_since: null description: Return data about the requested export location. name: share_instance_export_location:index operations: - method: POST path: /share_instances/{share_instance_id}/export_locations scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_instance_export_location:show deprecated_since: null description: Return data about the requested export location. name: share_instance_export_location:show operations: - method: GET path: /share_instances/{share_instance_id}/export_locations/{export_location_id} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_type:create deprecated_since: null description: Create share type. name: share_type:create operations: - method: POST path: /types scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_type:update deprecated_since: null description: Update share type. name: share_type:update operations: - method: PUT path: /types/{share_type_id} scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_type:show deprecated_since: null description: Get share type. name: share_type:show operations: - method: GET path: /types/{share_type_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_type:index deprecated_since: null description: List share types. name: share_type:index operations: - method: GET path: /types - method: GET path: /types?is_public=all scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_type:default deprecated_since: null description: Get default share type. name: share_type:default operations: - method: GET path: /types/default scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_type:delete deprecated_since: null description: Delete share type. name: share_type:delete operations: - method: DELETE path: /types/{share_type_id} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_type:list_project_access deprecated_since: null description: List share type project access. name: share_type:list_project_access operations: - method: GET path: /types/{share_type_id} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_type:add_project_access deprecated_since: null description: Add share type to project. name: share_type:add_project_access operations: - method: POST path: /types/{share_type_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_type:remove_project_access deprecated_since: null description: Remove share type from project. name: share_type:remove_project_access operations: - method: POST path: /types/{share_type_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_types_extra_spec:create deprecated_since: null description: Create share type extra spec. name: share_types_extra_spec:create operations: - method: POST path: /types/{share_type_id}/extra_specs scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_types_extra_spec:show deprecated_since: null description: Get share type extra specs of a given share type. name: share_types_extra_spec:show operations: - method: GET path: /types/{share_type_id}/extra_specs scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_types_extra_spec:index deprecated_since: null description: Get details of a share type extra spec. name: share_types_extra_spec:index operations: - method: GET path: /types/{share_type_id}/extra_specs/{extra_spec_id} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_types_extra_spec:update deprecated_since: null description: Update share type extra spec. name: share_types_extra_spec:update operations: - method: PUT path: /types/{share_type_id}/extra_specs scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_types_extra_spec:delete deprecated_since: null description: Delete share type extra spec. name: share_types_extra_spec:delete operations: - method: DELETE path: /types/{share_type_id}/extra_specs/{key} scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot:get_snapshot deprecated_since: null description: Get share snapshot. name: share_snapshot:get_snapshot operations: - method: GET path: /snapshots/{snapshot_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot:get_all_snapshots deprecated_since: null description: Get all share snapshots. name: share_snapshot:get_all_snapshots operations: - method: GET path: /snapshots - method: GET path: /snapshots/detail - method: GET path: /snapshots?{query} - method: GET path: /snapshots/detail?{query} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot:force_delete deprecated_since: null description: Force Delete a share snapshot. name: share_snapshot:force_delete operations: - method: DELETE path: /snapshots/{snapshot_id} scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot:manage_snapshot deprecated_since: null description: Manage share snapshot. name: share_snapshot:manage_snapshot operations: - method: POST path: /snapshots/manage scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot:unmanage_snapshot deprecated_since: null description: Unmanage share snapshot. name: share_snapshot:unmanage_snapshot operations: - method: POST path: /snapshots/{snapshot_id}/action scope_types: - system - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot:reset_status deprecated_since: null description: Reset status. name: share_snapshot:reset_status operations: - method: POST path: /snapshots/{snapshot_id}/action scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot:access_list deprecated_since: null description: List access rules of a share snapshot. name: share_snapshot:access_list operations: - method: GET path: /snapshots/{snapshot_id}/access-list scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot:allow_access deprecated_since: null description: Allow access to a share snapshot. name: share_snapshot:allow_access operations: - method: POST path: /snapshots/{snapshot_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot:deny_access deprecated_since: null description: Deny access to a share snapshot. name: share_snapshot:deny_access operations: - method: POST path: /snapshots/{snapshot_id}/action scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot_export_location:index deprecated_since: null description: List export locations of a share snapshot. name: share_snapshot_export_location:index operations: - method: GET path: /snapshots/{snapshot_id}/export-locations/ scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_snapshot_export_location:show deprecated_since: null description: Get details of a specified export location of a share snapshot. name: share_snapshot_export_location:show operations: - method: GET path: /snapshots/{snapshot_id}/export-locations/{export_location_id} scope_types: - system - project - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot_instance:show deprecated_since: null description: Get share snapshot instance. name: share_snapshot_instance:show operations: - method: GET path: /snapshot-instances/{snapshot_instance_id} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot_instance:index deprecated_since: null description: Get all share snapshot instances. name: share_snapshot_instance:index operations: - method: GET path: /snapshot-instances - method: GET path: /snapshot-instances?{query} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot_instance:detail deprecated_since: null description: Get details of share snapshot instances. name: share_snapshot_instance:detail operations: - method: GET path: /snapshot-instances/detail - method: GET path: /snapshot-instances/detail?{query} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot_instance:reset_status deprecated_since: null description: Reset share snapshot instance's status. name: share_snapshot_instance:reset_status operations: - method: POST path: /snapshot-instances/{snapshot_instance_id}/action scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot_instance_export_location:index deprecated_since: null description: List export locations of a share snapshot instance. name: share_snapshot_instance_export_location:index operations: - method: GET path: /snapshot-instances/{snapshot_instance_id}/export-locations scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_snapshot_instance_export_location:show deprecated_since: null description: Show details of a specified export location of a share snapshot instance. name: share_snapshot_instance_export_location:show operations: - method: GET path: /snapshot-instances/{snapshot_instance_id}/export-locations/{export_location_id} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:index deprecated_since: null description: Get share servers. name: share_server:index operations: - method: GET path: /share-servers - method: GET path: /share-servers?{query} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:show deprecated_since: null description: Show share server. name: share_server:show operations: - method: GET path: /share-servers/{server_id} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:details deprecated_since: null description: Get share server details. name: share_server:details operations: - method: GET path: /share-servers/{server_id}/details scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:delete deprecated_since: null description: Delete share server. name: share_server:delete operations: - method: DELETE path: /share-servers/{server_id} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:manage_share_server deprecated_since: null description: Manage share server. name: share_server:manage_share_server operations: - method: POST path: /share-servers/manage scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:unmanage_share_server deprecated_since: null description: Unmanage share server. name: share_server:unmanage_share_server operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:reset_status deprecated_since: null description: Reset the status of a share server. name: share_server:reset_status operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:share_server_migration_start deprecated_since: null description: Migrates a share server to the specified host. name: share_server:share_server_migration_start operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:share_server_migration_check deprecated_since: null description: Check if can migrates a share server to the specified host. name: share_server:share_server_migration_check operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:share_server_migration_complete deprecated_since: null description: Invokes the 2nd phase of share server migration. name: share_server:share_server_migration_complete operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:share_server_migration_cancel deprecated_since: null description: Attempts to cancel share server migration. name: share_server:share_server_migration_cancel operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:share_server_migration_get_progress deprecated_since: null description: Retrieves the share server migration progress for a given share server. name: share_server:share_server_migration_get_progress operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_server:share_server_reset_task_state deprecated_since: null description: Resets task state. name: share_server:share_server_reset_task_state operations: - method: POST path: /share-servers/{share_server_id}/action scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: service:index deprecated_since: null description: Return a list of all running services. name: service:index operations: - method: GET path: /os-services - method: GET path: /os-services?{query} - method: GET path: /services - method: GET path: /services?{query} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: service:update deprecated_since: null description: Enable/Disable scheduling for a service. name: service:update operations: - method: PUT path: /os-services/disable - method: PUT path: /os-services/enable - method: PUT path: /services/disable - method: PUT path: /services/enable scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: quota_set:update deprecated_since: null description: Update the quotas for a project/user and/or share type. name: quota_set:update operations: - method: PUT path: /quota-sets/{tenant_id} - method: PUT path: /quota-sets/{tenant_id}?user_id={user_id} - method: PUT path: /quota-sets/{tenant_id}?share_type={share_type_id} - method: PUT path: /os-quota-sets/{tenant_id} - method: PUT path: /os-quota-sets/{tenant_id}?user_id={user_id} scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: quota_set:show deprecated_since: null description: List the quotas for a tenant/user. name: quota_set:show operations: - method: GET path: /quota-sets/{tenant_id}/defaults - method: GET path: /os-quota-sets/{tenant_id}/defaults scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: quota_set:delete deprecated_since: null description: Delete quota for a tenant/user or tenant/share-type. The quota will revert back to default (Admin only). name: quota_set:delete operations: - method: DELETE path: /quota-sets/{tenant_id} - method: DELETE path: /quota-sets/{tenant_id}?user_id={user_id} - method: DELETE path: /quota-sets/{tenant_id}?share_type={share_type_id} - method: DELETE path: /os-quota-sets/{tenant_id} - method: DELETE path: /os-quota-sets/{tenant_id}?user_id={user_id} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: quota_class_set:update deprecated_since: null description: Update quota class. name: quota_class_set:update operations: - method: PUT path: /quota-class-sets/{class_name} - method: PUT path: /os-quota-class-sets/{class_name} scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: quota_class_set:show deprecated_since: null description: Get quota class. name: quota_class_set:show operations: - method: GET path: /quota-class-sets/{class_name} - method: GET path: /os-quota-class-sets/{class_name} scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_types_spec:create deprecated_since: null description: Create share group type specs. name: share_group_types_spec:create operations: - method: POST path: /share-group-types/{share_group_type_id}/group-specs scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_types_spec:index deprecated_since: null description: Get share group type specs. name: share_group_types_spec:index operations: - method: GET path: /share-group-types/{share_group_type_id}/group-specs scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_types_spec:show deprecated_since: null description: Get details of a share group type spec. name: share_group_types_spec:show operations: - method: GET path: /share-group-types/{share_group_type_id}/group-specs/{key} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_types_spec:update deprecated_since: null description: Update a share group type spec. name: share_group_types_spec:update operations: - method: PUT path: /share-group-types/{share_group_type_id}/group-specs/{key} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_types_spec:delete deprecated_since: null description: Delete a share group type spec. name: share_group_types_spec:delete operations: - method: DELETE path: /share-group-types/{share_group_type_id}/group-specs/{key} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_type:create deprecated_since: null description: Create a new share group type. name: share_group_type:create operations: - method: POST path: /share-group-types scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_type:index deprecated_since: null description: Get the list of share group types. name: share_group_type:index operations: - method: GET path: /share-group-types - method: GET path: /share-group-types?is_public=all scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_type:show deprecated_since: null description: Get details regarding the specified share group type. name: share_group_type:show operations: - method: GET path: /share-group-types/{share_group_type_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_type:default deprecated_since: null description: Get the default share group type. name: share_group_type:default operations: - method: GET path: /share-group-types/default scope_types: - system - project - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_type:delete deprecated_since: null description: Delete an existing group type. name: share_group_type:delete operations: - method: DELETE path: /share-group-types/{share_group_type_id} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_type:list_project_access deprecated_since: null description: Get project access by share group type. name: share_group_type:list_project_access operations: - method: GET path: /share-group-types/{share_group_type_id}/access scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_type:add_project_access deprecated_since: null description: Allow project to use the share group type. name: share_group_type:add_project_access operations: - method: POST path: /share-group-types/{share_group_type_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_type:remove_project_access deprecated_since: null description: Deny project access to use the share group type. name: share_group_type:remove_project_access operations: - method: POST path: /share-group-types/{share_group_type_id}/action scope_types: - system - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_snapshot:create deprecated_since: null description: Create a new share group snapshot. name: share_group_snapshot:create operations: - method: POST path: /share-group-snapshots scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_snapshot:get deprecated_since: null description: Get details of a share group snapshot. name: share_group_snapshot:get operations: - method: GET path: /share-group-snapshots/{share_group_snapshot_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_snapshot:get_all deprecated_since: null description: Get all share group snapshots. name: share_group_snapshot:get_all operations: - method: GET path: /share-group-snapshots - method: GET path: /share-group-snapshots/detail - method: GET path: /share-group-snapshots/{query} - method: GET path: /share-group-snapshots/detail?{query} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_snapshot:update deprecated_since: null description: Update a share group snapshot. name: share_group_snapshot:update operations: - method: PUT path: /share-group-snapshots/{share_group_snapshot_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group_snapshot:delete deprecated_since: null description: Delete a share group snapshot. name: share_group_snapshot:delete operations: - method: DELETE path: /share-group-snapshots/{share_group_snapshot_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_snapshot:force_delete deprecated_since: null description: Force delete a share group snapshot. name: share_group_snapshot:force_delete operations: - method: POST path: /share-group-snapshots/{share_group_snapshot_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group_snapshot:reset_status deprecated_since: null description: Reset a share group snapshot's status. name: share_group_snapshot:reset_status operations: - method: POST path: /share-group-snapshots/{share_group_snapshot_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group:create deprecated_since: null description: Create share group. name: share_group:create operations: - method: POST path: /share-groups scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group:get deprecated_since: null description: Get details of a share group. name: share_group:get operations: - method: GET path: /share-groups/{share_group_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group:get_all deprecated_since: null description: Get all share groups. name: share_group:get_all operations: - method: GET path: /share-groups - method: GET path: /share-groups/detail - method: GET path: /share-groups?{query} - method: GET path: /share-groups/detail?{query} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group:update deprecated_since: null description: Update share group. name: share_group:update operations: - method: PUT path: /share-groups/{share_group_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_group:delete deprecated_since: null description: Delete share group. name: share_group:delete operations: - method: DELETE path: /share-groups/{share_group_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group:force_delete deprecated_since: null description: Force delete a share group. name: share_group:force_delete operations: - method: POST path: /share-groups/{share_group_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_group:reset_status deprecated_since: null description: Reset share group's status. name: share_group:reset_status operations: - method: POST path: /share-groups/{share_group_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica:create deprecated_since: null description: Create share replica. name: share_replica:create operations: - method: POST path: /share-replicas scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica:get_all deprecated_since: null description: Get all share replicas. name: share_replica:get_all operations: - method: GET path: /share-replicas - method: GET path: /share-replicas/detail - method: GET path: /share-replicas/detail?share_id={share_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica:show deprecated_since: null description: Get details of a share replica. name: share_replica:show operations: - method: GET path: /share-replicas/{share_replica_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica:delete deprecated_since: null description: Delete a share replica. name: share_replica:delete operations: - method: DELETE path: /share-replicas/{share_replica_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_replica:force_delete deprecated_since: null description: Force delete a share replica. name: share_replica:force_delete operations: - method: POST path: /share-replicas/{share_replica_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica:promote deprecated_since: null description: Promote a non-active share replica to active. name: share_replica:promote operations: - method: POST path: /share-replicas/{share_replica_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_replica:resync deprecated_since: null description: Resync a share replica that is out of sync. name: share_replica:resync operations: - method: POST path: /share-replicas/{share_replica_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_replica:reset_replica_state deprecated_since: null description: Reset share replica's replica_state attribute. name: share_replica:reset_replica_state operations: - method: POST path: /share-replicas/{share_replica_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_replica:reset_status deprecated_since: null description: Reset share replica's status. name: share_replica:reset_status operations: - method: POST path: /share-replicas/{share_replica_id}/action scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica_export_location:index deprecated_since: null description: Get all export locations of a given share replica. name: share_replica_export_location:index operations: - method: GET path: /share-replicas/{share_replica_id}/export-locations scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_replica_export_location:show deprecated_since: null description: Get details about the requested share replica export location. name: share_replica_export_location:show operations: - method: GET path: /share-replicas/{share_replica_id}/export-locations/{export_location_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:create deprecated_since: null description: Create share network. name: share_network:create operations: - method: POST path: /share-networks scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:show deprecated_since: null description: Get details of a share network. name: share_network:show operations: - method: GET path: /share-networks/{share_network_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:index deprecated_since: null description: Get all share networks. name: share_network:index operations: - method: GET path: /share-networks - method: GET path: /share-networks?{query} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:detail deprecated_since: null description: Get details of share networks . name: share_network:detail operations: - method: GET path: /share-networks/detail?{query} - method: GET path: /share-networks/detail scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:update deprecated_since: null description: Update a share network. name: share_network:update operations: - method: PUT path: /share-networks/{share_network_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:delete deprecated_since: null description: Delete a share network. name: share_network:delete operations: - method: DELETE path: /share-networks/{share_network_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:add_security_service deprecated_since: null description: Add security service to share network. name: share_network:add_security_service operations: - method: POST path: /share-networks/{share_network_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:add_security_service_check deprecated_since: null description: Check the feasibility of add security service to a share network. name: share_network:add_security_service_check operations: - method: POST path: /share-networks/{share_network_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:remove_security_service deprecated_since: null description: Remove security service from share network. name: share_network:remove_security_service operations: - method: POST path: /share-networks/{share_network_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:update_security_service deprecated_since: null description: Update security service from share network. name: share_network:update_security_service operations: - method: POST path: /share-networks/{share_network_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network:update_security_service_check deprecated_since: null description: Check the feasibility of update a security service from share network. name: share_network:update_security_service_check operations: - method: POST path: /share-networks/{share_network_id}/action scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-admin) deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_network:reset_status deprecated_since: null description: Reset share network`s status. name: share_network:reset_status operations: - method: POST path: /share-networks/{share_network_id}/action scope_types: - system - project - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_network:get_all_share_networks deprecated_since: null description: Get share networks belonging to all projects. name: share_network:get_all_share_networks operations: - method: GET path: /share-networks?all_tenants=1 - method: GET path: /share-networks/detail?all_tenants=1 scope_types: - system - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network_subnet:create deprecated_since: null description: Create a new share network subnet. name: share_network_subnet:create operations: - method: POST path: /share-networks/{share_network_id}/subnets scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network_subnet:delete deprecated_since: null description: Delete a share network subnet. name: share_network_subnet:delete operations: - method: DELETE path: /share-networks/{share_network_id}/subnets/{share_network_subnet_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network_subnet:show deprecated_since: null description: Shows a share network subnet. name: share_network_subnet:show operations: - method: GET path: /share-networks/{share_network_id}/subnets/{share_network_subnet_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_network_subnet:index deprecated_since: null description: Get all share network subnets. name: share_network_subnet:index operations: - method: GET path: /share-networks/{share_network_id}/subnets scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: security_service:create deprecated_since: null description: Create security service. name: security_service:create operations: - method: POST path: /security-services scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: security_service:show deprecated_since: null description: Get details of a security service. name: security_service:show operations: - method: GET path: /security-services/{security_service_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: security_service:detail deprecated_since: null description: Get details of all security services. name: security_service:detail operations: - method: GET path: /security-services/detail?{query} - method: GET path: /security-services/detail scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: security_service:index deprecated_since: null description: Get all security services. name: security_service:index operations: - method: GET path: /security-services - method: GET path: /security-services?{query} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: security_service:update deprecated_since: null description: Update a security service. name: security_service:update operations: - method: PUT path: /security-services/{security_service_id} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: security_service:delete deprecated_since: null description: Delete a security service. name: security_service:delete operations: - method: DELETE path: /security-services/{security_service_id} scope_types: - system - project - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: security_service:get_all_security_services deprecated_since: null description: Get security services of all projects. name: security_service:get_all_security_services operations: - method: GET path: /security-services?all_tenants=1 - method: GET path: /security-services/detail?all_tenants=1 scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_export_location:index deprecated_since: null description: Get all export locations of a given share. name: share_export_location:index operations: - method: GET path: /shares/{share_id}/export_locations scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_export_location:show deprecated_since: null description: Get details about the requested export location. name: share_export_location:show operations: - method: GET path: /shares/{share_id}/export_locations/{export_location_id} scope_types: - system - project - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_instance:index deprecated_since: null description: Get all share instances. name: share_instance:index operations: - method: GET path: /share_instances - method: GET path: /share_instances?{query} scope_types: - system - check_str: rule:system-reader deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_instance:show deprecated_since: null description: Get details of a share instance. name: share_instance:show operations: - method: GET path: /share_instances/{share_instance_id} scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_instance:force_delete deprecated_since: null description: Force delete a share instance. name: share_instance:force_delete operations: - method: POST path: /share_instances/{share_instance_id}/action scope_types: - system - check_str: rule:system-admin deprecated_reason: null deprecated_rule: check_str: rule:admin_api name: share_instance:reset_status deprecated_since: null description: Reset share instance's status. name: share_instance:reset_status operations: - method: POST path: /share_instances/{share_instance_id}/action scope_types: - system - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: message:get deprecated_since: null description: Get details of a given message. name: message:get operations: - method: GET path: /messages/{message_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: message:get_all deprecated_since: null description: Get all messages. name: message:get_all operations: - method: GET path: /messages - method: GET path: /messages?{query} scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: message:delete deprecated_since: null description: Delete a message. name: message:delete operations: - method: DELETE path: /messages/{message_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_access_rule:get deprecated_since: null description: Get details of a share access rule. name: share_access_rule:get operations: - method: GET path: /share-access-rules/{share_access_id} scope_types: - system - project - check_str: (rule:system-reader) or (rule:project-reader) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_access_rule:index deprecated_since: null description: List access rules of a given share. name: share_access_rule:index operations: - method: GET path: /share-access-rules?share_id={share_id}&key1=value1&key2=value2 scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_access_metadata:update deprecated_since: null description: Set metadata for a share access rule. name: share_access_metadata:update operations: - method: PUT path: /share-access-rules/{share_access_id}/metadata scope_types: - system - project - check_str: (rule:system-admin) or (rule:project-member) deprecated_reason: null deprecated_rule: check_str: rule:default name: share_access_metadata:delete deprecated_since: null description: Delete metadata for a share access rule. name: share_access_metadata:delete operations: - method: DELETE path: /share-access-rules/{share_access_id}/metadata/{key} scope_types: - system - project ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/conf/manila_policy.yaml0000664000175000017500000021110100000000000022053 0ustar00zuulzuul00000000000000# Intended scope(s): system #"system-admin": "role:admin and system_scope:all" # Intended scope(s): system #"system-member": "role:member and system_scope:all" # Intended scope(s): system #"system-reader": "role:reader and system_scope:all" # Intended scope(s): project #"project-admin": "role:admin and project_id:%(project_id)s" # Intended scope(s): project #"project-member": "role:member and project_id:%(project_id)s" # Intended scope(s): project #"project-reader": "role:reader and project_id:%(project_id)s" # Intended scope(s): system #"context_is_admin": "rule:system-admin" # DEPRECATED # "context_is_admin":"role:admin" has been deprecated since W in favor # of "context_is_admin":"rule:system-admin". # The `context_is_admin` check is superseded by more specific check # strings that consume system and project scope attributes from # keystone tokens. #"admin_or_owner": "is_admin:True or project_id:%(project_id)s" #"default": "rule:admin_or_owner" #"admin_api": "is_admin:True" # Get all storage availability zones. # GET /os-availability-zone # GET /availability-zone # Intended scope(s): system, project #"availability_zone:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "availability_zone:index":"rule:default" has been deprecated since W # in favor of "availability_zone:index":"(rule:system-reader) or # (rule:project-reader)". # The availability zone API now supports system scope and default # roles. # Get information regarding backends (and storage pools) known to the # scheduler. # GET /scheduler-stats/pools # GET /scheduler-stats/pools?{query} # Intended scope(s): system #"scheduler_stats:pools:index": "rule:system-reader" # DEPRECATED # "scheduler_stats:pools:index":"rule:admin_api" has been deprecated # since W in favor of "scheduler_stats:pools:index":"rule:system- # reader". # The storage pool statistics API now support system scope and default # roles. # Get detailed information regarding backends (and storage pools) # known to the scheduler. # GET /scheduler-stats/pools/detail?{query} # GET /scheduler-stats/pools/detail # Intended scope(s): system #"scheduler_stats:pools:detail": "rule:system-reader" # DEPRECATED # "scheduler_stats:pools:detail":"rule:admin_api" has been deprecated # since W in favor of "scheduler_stats:pools:detail":"rule:system- # reader". # The storage pool statistics API now support system scope and default # roles. # Create share. # POST /shares # Intended scope(s): system, project #"share:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:create":"" has been deprecated since W in favor of # "share:create":"(rule:system-admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Create shares visible across all projects in the cloud. # POST /shares # Intended scope(s): system #"share:create_public_share": "rule:system-admin" # DEPRECATED # "share:create_public_share":"rule:admin_api" has been deprecated # since W in favor of "share:create_public_share":"rule:system-admin". # The share API now supports system scope and default roles. # Get share. # GET /shares/{share_id} # Intended scope(s): system, project #"share:get": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share:get":"rule:default" has been deprecated since W in favor of # "share:get":"(rule:system-reader) or (rule:project-reader)". # The share API now supports system scope and default roles. # List shares. # GET /shares # GET /shares/detail # Intended scope(s): system, project #"share:get_all": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share:get_all":"rule:default" has been deprecated since W in favor # of "share:get_all":"(rule:system-reader) or (rule:project-reader)". # The share API now supports system scope and default roles. # Update share. # PUT /shares # Intended scope(s): system, project #"share:update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:update":"rule:default" has been deprecated since W in favor # of "share:update":"(rule:system-admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Update shares to be visible across all projects in the cloud. # PUT /shares # Intended scope(s): system #"share:set_public_share": "rule:system-admin" # DEPRECATED # "share:set_public_share":"rule:admin_api" has been deprecated since # W in favor of "share:set_public_share":"rule:system-admin". # The share API now supports system scope and default roles. # Delete share. # DELETE /shares/{share_id} # Intended scope(s): system, project #"share:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:delete":"rule:default" has been deprecated since W in favor # of "share:delete":"(rule:system-admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Force Delete a share. # DELETE /shares/{share_id} # Intended scope(s): system, project #"share:force_delete": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share:force_delete":"rule:admin_api" has been deprecated since W in # favor of "share:force_delete":"(rule:system-admin) or (rule:project- # admin)". # The share API now supports system scope and default roles. # Manage share. # POST /shares/manage # Intended scope(s): system #"share:manage": "rule:system-admin" # DEPRECATED # "share:manage":"rule:admin_api" has been deprecated since W in favor # of "share:manage":"rule:system-admin". # The share API now supports system scope and default roles. # Unmanage share. # POST /shares/unmanage # Intended scope(s): system #"share:unmanage": "rule:system-admin" # DEPRECATED # "share:unmanage":"rule:admin_api" has been deprecated since W in # favor of "share:unmanage":"rule:system-admin". # The share API now supports system scope and default roles. # List share by host. # GET /shares # GET /shares/detail # Intended scope(s): system #"share:list_by_host": "rule:system-reader" # DEPRECATED # "share:list_by_host":"rule:admin_api" has been deprecated since W in # favor of "share:list_by_host":"rule:system-reader". # The share API now supports system scope and default roles. # List share by server id. # GET /shares # GET /shares/detail # Intended scope(s): system #"share:list_by_share_server_id": "rule:system-reader" # DEPRECATED # "share:list_by_share_server_id":"rule:admin_api" has been deprecated # since W in favor of "share:list_by_share_server_id":"rule:system- # reader". # The share API now supports system scope and default roles. # Get share access rule, it under deny access operation. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:access_get": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share:access_get":"rule:default" has been deprecated since W in # favor of "share:access_get":"(rule:system-reader) or (rule:project- # reader)". # The share API now supports system scope and default roles. # List share access rules. # GET /shares/{share_id}/action # Intended scope(s): system, project #"share:access_get_all": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share:access_get_all":"rule:default" has been deprecated since W in # favor of "share:access_get_all":"(rule:system-reader) or # (rule:project-reader)". # The share API now supports system scope and default roles. # Extend share. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:extend": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:extend":"rule:default" has been deprecated since W in favor # of "share:extend":"(rule:system-admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Shrink share. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:shrink": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:shrink":"rule:default" has been deprecated since W in favor # of "share:shrink":"(rule:system-admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Migrate a share to the specified host. # POST /shares/{share_id}/action # Intended scope(s): system #"share:migration_start": "rule:system-admin" # DEPRECATED # "share:migration_start":"rule:admin_api" has been deprecated since W # in favor of "share:migration_start":"rule:system-admin". # The share API now supports system scope and default roles. # Invokes 2nd phase of share migration. # POST /shares/{share_id}/action # Intended scope(s): system #"share:migration_complete": "rule:system-admin" # DEPRECATED # "share:migration_complete":"rule:admin_api" has been deprecated # since W in favor of "share:migration_complete":"rule:system-admin". # The share API now supports system scope and default roles. # Attempts to cancel share migration. # POST /shares/{share_id}/action # Intended scope(s): system #"share:migration_cancel": "rule:system-admin" # DEPRECATED # "share:migration_cancel":"rule:admin_api" has been deprecated since # W in favor of "share:migration_cancel":"rule:system-admin". # The share API now supports system scope and default roles. # Retrieve share migration progress for a given share. # POST /shares/{share_id}/action # Intended scope(s): system #"share:migration_get_progress": "rule:system-reader" # DEPRECATED # "share:migration_get_progress":"rule:admin_api" has been deprecated # since W in favor of "share:migration_get_progress":"rule:system- # reader". # The share API now supports system scope and default roles. # Reset task state. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:reset_task_state": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share:reset_task_state":"rule:admin_api" has been deprecated since # W in favor of "share:reset_task_state":"(rule:system-admin) or # (rule:project-admin)". # The share API now supports system scope and default roles. # Reset status. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:reset_status": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share:reset_status":"rule:admin_api" has been deprecated since W in # favor of "share:reset_status":"(rule:system-admin) or (rule:project- # admin)". # The share API now supports system scope and default roles. # Revert a share to a snapshot. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:revert_to_snapshot": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:revert_to_snapshot":"rule:default" has been deprecated since # W in favor of "share:revert_to_snapshot":"(rule:system-admin) or # (rule:project-member)". # The share API now supports system scope and default roles. # Add share access rule. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:allow_access": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:allow_access":"rule:default" has been deprecated since W in # favor of "share:allow_access":"(rule:system-admin) or (rule:project- # member)". # The share API now supports system scope and default roles. # Remove share access rule. # POST /shares/{share_id}/action # Intended scope(s): system, project #"share:deny_access": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:deny_access":"rule:default" has been deprecated since W in # favor of "share:deny_access":"(rule:system-admin) or (rule:project- # member)". # The share API now supports system scope and default roles. # Update share metadata. # PUT /shares/{share_id}/metadata # Intended scope(s): system, project #"share:update_share_metadata": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:update_share_metadata":"rule:default" has been deprecated # since W in favor of "share:update_share_metadata":"(rule:system- # admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Delete share metadata. # DELETE /shares/{share_id}/metadata/{key} # Intended scope(s): system, project #"share:delete_share_metadata": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:delete_share_metadata":"rule:default" has been deprecated # since W in favor of "share:delete_share_metadata":"(rule:system- # admin) or (rule:project-member)". # The share API now supports system scope and default roles. # Get share metadata. # GET /shares/{share_id}/metadata # Intended scope(s): system, project #"share:get_share_metadata": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share:get_share_metadata":"rule:default" has been deprecated since # W in favor of "share:get_share_metadata":"(rule:system-reader) or # (rule:project-reader)". # The share API now supports system scope and default roles. # Create share snapshot. # POST /snapshots # Intended scope(s): system, project #"share:create_snapshot": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:create_snapshot":"rule:default" has been deprecated since W # in favor of "share:create_snapshot":"(rule:system-admin) or # (rule:project-member)". # The share API now supports system scope and default roles. # Delete share snapshot. # DELETE /snapshots/{snapshot_id} # Intended scope(s): system, project #"share:delete_snapshot": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:delete_snapshot":"rule:default" has been deprecated since W # in favor of "share:delete_snapshot":"(rule:system-admin) or # (rule:project-member)". # The share API now supports system scope and default roles. # Update share snapshot. # PUT /snapshots/{snapshot_id}/action # Intended scope(s): system, project #"share:snapshot_update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share:snapshot_update":"rule:default" has been deprecated since W # in favor of "share:snapshot_update":"(rule:system-admin) or # (rule:project-member)". # The share API now supports system scope and default roles. # Return data about the requested export location. # POST /share_instances/{share_instance_id}/export_locations # Intended scope(s): system #"share_instance_export_location:index": "rule:system-reader" # DEPRECATED # "share_instance_export_location:index":"rule:admin_api" has been # deprecated since W in favor of # "share_instance_export_location:index":"rule:system-reader". # The share instance export location API now supports system scope and # default roles. # Return data about the requested export location. # GET /share_instances/{share_instance_id}/export_locations/{export_location_id} # Intended scope(s): system #"share_instance_export_location:show": "rule:system-reader" # DEPRECATED # "share_instance_export_location:show":"rule:admin_api" has been # deprecated since W in favor of # "share_instance_export_location:show":"rule:system-reader". # The share instance export location API now supports system scope and # default roles. # Create share type. # POST /types # Intended scope(s): system #"share_type:create": "rule:system-admin" # DEPRECATED # "share_type:create":"rule:admin_api" has been deprecated since W in # favor of "share_type:create":"rule:system-admin". # The share type API now supports system scope and default roles. # Update share type. # PUT /types/{share_type_id} # Intended scope(s): system #"share_type:update": "rule:system-admin" # DEPRECATED # "share_type:update":"rule:admin_api" has been deprecated since W in # favor of "share_type:update":"rule:system-admin". # The share type API now supports system scope and default roles. # Get share type. # GET /types/{share_type_id} # Intended scope(s): system, project #"share_type:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_type:show":"rule:default" has been deprecated since W in # favor of "share_type:show":"(rule:system-reader) or (rule:project- # reader)". # The share type API now supports system scope and default roles. # List share types. # GET /types # GET /types?is_public=all # Intended scope(s): system, project #"share_type:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_type:index":"rule:default" has been deprecated since W in # favor of "share_type:index":"(rule:system-reader) or (rule:project- # reader)". # The share type API now supports system scope and default roles. # Get default share type. # GET /types/default # Intended scope(s): system, project #"share_type:default": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_type:default":"rule:default" has been deprecated since W in # favor of "share_type:default":"(rule:system-reader) or # (rule:project-reader)". # The share type API now supports system scope and default roles. # Delete share type. # DELETE /types/{share_type_id} # Intended scope(s): system #"share_type:delete": "rule:system-admin" # DEPRECATED # "share_type:delete":"rule:admin_api" has been deprecated since W in # favor of "share_type:delete":"rule:system-admin". # The share type API now supports system scope and default roles. # List share type project access. # GET /types/{share_type_id} # Intended scope(s): system #"share_type:list_project_access": "rule:system-reader" # DEPRECATED # "share_type:list_project_access":"rule:admin_api" has been # deprecated since W in favor of # "share_type:list_project_access":"rule:system-reader". # The share type API now supports system scope and default roles. # Add share type to project. # POST /types/{share_type_id}/action # Intended scope(s): system #"share_type:add_project_access": "rule:system-admin" # DEPRECATED # "share_type:add_project_access":"rule:admin_api" has been deprecated # since W in favor of "share_type:add_project_access":"rule:system- # admin". # The share type API now supports system scope and default roles. # Remove share type from project. # POST /types/{share_type_id}/action # Intended scope(s): system #"share_type:remove_project_access": "rule:system-admin" # DEPRECATED # "share_type:remove_project_access":"rule:admin_api" has been # deprecated since W in favor of # "share_type:remove_project_access":"rule:system-admin". # The share type API now supports system scope and default roles. # Create share type extra spec. # POST /types/{share_type_id}/extra_specs # Intended scope(s): system #"share_types_extra_spec:create": "rule:system-admin" # DEPRECATED # "share_types_extra_spec:create":"rule:admin_api" has been deprecated # since W in favor of "share_types_extra_spec:create":"rule:system- # admin". # The share types extra specs API now supports system scope and # default roles. # Get share type extra specs of a given share type. # GET /types/{share_type_id}/extra_specs # Intended scope(s): system #"share_types_extra_spec:show": "rule:system-reader" # DEPRECATED # "share_types_extra_spec:show":"rule:admin_api" has been deprecated # since W in favor of "share_types_extra_spec:show":"rule:system- # reader". # The share types extra specs API now supports system scope and # default roles. # Get details of a share type extra spec. # GET /types/{share_type_id}/extra_specs/{extra_spec_id} # Intended scope(s): system #"share_types_extra_spec:index": "rule:system-reader" # DEPRECATED # "share_types_extra_spec:index":"rule:admin_api" has been deprecated # since W in favor of "share_types_extra_spec:index":"rule:system- # reader". # The share types extra specs API now supports system scope and # default roles. # Update share type extra spec. # PUT /types/{share_type_id}/extra_specs # Intended scope(s): system #"share_types_extra_spec:update": "rule:system-admin" # DEPRECATED # "share_types_extra_spec:update":"rule:admin_api" has been deprecated # since W in favor of "share_types_extra_spec:update":"rule:system- # admin". # The share types extra specs API now supports system scope and # default roles. # Delete share type extra spec. # DELETE /types/{share_type_id}/extra_specs/{key} # Intended scope(s): system #"share_types_extra_spec:delete": "rule:system-admin" # DEPRECATED # "share_types_extra_spec:delete":"rule:admin_api" has been deprecated # since W in favor of "share_types_extra_spec:delete":"rule:system- # admin". # The share types extra specs API now supports system scope and # default roles. # Get share snapshot. # GET /snapshots/{snapshot_id} # Intended scope(s): system, project #"share_snapshot:get_snapshot": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_snapshot:get_snapshot":"rule:default" has been deprecated # since W in favor of "share_snapshot:get_snapshot":"(rule:system- # reader) or (rule:project-reader)". # The share snapshot API now supports system scope and default roles. # Get all share snapshots. # GET /snapshots # GET /snapshots/detail # GET /snapshots?{query} # GET /snapshots/detail?{query} # Intended scope(s): system, project #"share_snapshot:get_all_snapshots": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_snapshot:get_all_snapshots":"rule:default" has been # deprecated since W in favor of # "share_snapshot:get_all_snapshots":"(rule:system-reader) or # (rule:project-reader)". # The share snapshot API now supports system scope and default roles. # Force Delete a share snapshot. # DELETE /snapshots/{snapshot_id} # Intended scope(s): system, project #"share_snapshot:force_delete": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_snapshot:force_delete":"rule:admin_api" has been deprecated # since W in favor of "share_snapshot:force_delete":"(rule:system- # admin) or (rule:project-admin)". # The share snapshot API now supports system scope and default roles. # Manage share snapshot. # POST /snapshots/manage # Intended scope(s): system #"share_snapshot:manage_snapshot": "rule:system-admin" # DEPRECATED # "share_snapshot:manage_snapshot":"rule:admin_api" has been # deprecated since W in favor of # "share_snapshot:manage_snapshot":"rule:system-admin". # The share snapshot API now supports system scope and default roles. # Unmanage share snapshot. # POST /snapshots/{snapshot_id}/action # Intended scope(s): system #"share_snapshot:unmanage_snapshot": "rule:system-admin" # DEPRECATED # "share_snapshot:unmanage_snapshot":"rule:admin_api" has been # deprecated since W in favor of # "share_snapshot:unmanage_snapshot":"rule:system-admin". # The share snapshot API now supports system scope and default roles. # Reset status. # POST /snapshots/{snapshot_id}/action # Intended scope(s): system, project #"share_snapshot:reset_status": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_snapshot:reset_status":"rule:admin_api" has been deprecated # since W in favor of "share_snapshot:reset_status":"(rule:system- # admin) or (rule:project-admin)". # The share snapshot API now supports system scope and default roles. # List access rules of a share snapshot. # GET /snapshots/{snapshot_id}/access-list # Intended scope(s): system, project #"share_snapshot:access_list": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_snapshot:access_list":"rule:default" has been deprecated # since W in favor of "share_snapshot:access_list":"(rule:system- # reader) or (rule:project-reader)". # The share snapshot API now supports system scope and default roles. # Allow access to a share snapshot. # POST /snapshots/{snapshot_id}/action # Intended scope(s): system, project #"share_snapshot:allow_access": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_snapshot:allow_access":"rule:default" has been deprecated # since W in favor of "share_snapshot:allow_access":"(rule:system- # admin) or (rule:project-member)". # The share snapshot API now supports system scope and default roles. # Deny access to a share snapshot. # POST /snapshots/{snapshot_id}/action # Intended scope(s): system, project #"share_snapshot:deny_access": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_snapshot:deny_access":"rule:default" has been deprecated # since W in favor of "share_snapshot:deny_access":"(rule:system- # admin) or (rule:project-member)". # The share snapshot API now supports system scope and default roles. # List export locations of a share snapshot. # GET /snapshots/{snapshot_id}/export-locations/ # Intended scope(s): system, project #"share_snapshot_export_location:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_snapshot_export_location:index":"rule:default" has been # deprecated since W in favor of # "share_snapshot_export_location:index":"(rule:system-reader) or # (rule:project-reader)". # The share snapshot location API now supports system scope and # default roles. # Get details of a specified export location of a share snapshot. # GET /snapshots/{snapshot_id}/export-locations/{export_location_id} # Intended scope(s): system, project #"share_snapshot_export_location:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_snapshot_export_location:show":"rule:default" has been # deprecated since W in favor of # "share_snapshot_export_location:show":"(rule:system-reader) or # (rule:project-reader)". # The share snapshot location API now supports system scope and # default roles. # Get share snapshot instance. # GET /snapshot-instances/{snapshot_instance_id} # Intended scope(s): system #"share_snapshot_instance:show": "rule:system-reader" # DEPRECATED # "share_snapshot_instance:show":"rule:admin_api" has been deprecated # since W in favor of "share_snapshot_instance:show":"rule:system- # reader". # The share snapshot instance API now supports system scope and # default roles. # Get all share snapshot instances. # GET /snapshot-instances # GET /snapshot-instances?{query} # Intended scope(s): system #"share_snapshot_instance:index": "rule:system-reader" # DEPRECATED # "share_snapshot_instance:index":"rule:admin_api" has been deprecated # since W in favor of "share_snapshot_instance:index":"rule:system- # reader". # The share snapshot instance API now supports system scope and # default roles. # Get details of share snapshot instances. # GET /snapshot-instances/detail # GET /snapshot-instances/detail?{query} # Intended scope(s): system #"share_snapshot_instance:detail": "rule:system-reader" # DEPRECATED # "share_snapshot_instance:detail":"rule:admin_api" has been # deprecated since W in favor of # "share_snapshot_instance:detail":"rule:system-reader". # The share snapshot instance API now supports system scope and # default roles. # Reset share snapshot instance's status. # POST /snapshot-instances/{snapshot_instance_id}/action # Intended scope(s): system #"share_snapshot_instance:reset_status": "rule:system-admin" # DEPRECATED # "share_snapshot_instance:reset_status":"rule:admin_api" has been # deprecated since W in favor of # "share_snapshot_instance:reset_status":"rule:system-admin". # The share snapshot instance API now supports system scope and # default roles. # List export locations of a share snapshot instance. # GET /snapshot-instances/{snapshot_instance_id}/export-locations # Intended scope(s): system #"share_snapshot_instance_export_location:index": "rule:system-reader" # DEPRECATED # "share_snapshot_instance_export_location:index":"rule:admin_api" has # been deprecated since W in favor of # "share_snapshot_instance_export_location:index":"rule:system- # reader". # The share snapshot instance export location API now supports system # scope and default roles. # Show details of a specified export location of a share snapshot # instance. # GET /snapshot-instances/{snapshot_instance_id}/export-locations/{export_location_id} # Intended scope(s): system #"share_snapshot_instance_export_location:show": "rule:system-reader" # DEPRECATED # "share_snapshot_instance_export_location:show":"rule:admin_api" has # been deprecated since W in favor of # "share_snapshot_instance_export_location:show":"rule:system-reader". # The share snapshot instance export location API now supports system # scope and default roles. # Get share servers. # GET /share-servers # GET /share-servers?{query} # Intended scope(s): system #"share_server:index": "rule:system-reader" # DEPRECATED # "share_server:index":"rule:admin_api" has been deprecated since W in # favor of "share_server:index":"rule:system-reader". # The share server API now supports system scope and default roles. # Show share server. # GET /share-servers/{server_id} # Intended scope(s): system #"share_server:show": "rule:system-reader" # DEPRECATED # "share_server:show":"rule:admin_api" has been deprecated since W in # favor of "share_server:show":"rule:system-reader". # The share server API now supports system scope and default roles. # Get share server details. # GET /share-servers/{server_id}/details # Intended scope(s): system #"share_server:details": "rule:system-reader" # DEPRECATED # "share_server:details":"rule:admin_api" has been deprecated since W # in favor of "share_server:details":"rule:system-reader". # The share server API now supports system scope and default roles. # Delete share server. # DELETE /share-servers/{server_id} # Intended scope(s): system #"share_server:delete": "rule:system-admin" # DEPRECATED # "share_server:delete":"rule:admin_api" has been deprecated since W # in favor of "share_server:delete":"rule:system-admin". # The share server API now supports system scope and default roles. # Manage share server. # POST /share-servers/manage # Intended scope(s): system #"share_server:manage_share_server": "rule:system-admin" # DEPRECATED # "share_server:manage_share_server":"rule:admin_api" has been # deprecated since W in favor of # "share_server:manage_share_server":"rule:system-admin". # The share server API now supports system scope and default roles. # Unmanage share server. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:unmanage_share_server": "rule:system-admin" # DEPRECATED # "share_server:unmanage_share_server":"rule:admin_api" has been # deprecated since W in favor of # "share_server:unmanage_share_server":"rule:system-admin". # The share server API now supports system scope and default roles. # Reset the status of a share server. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:reset_status": "rule:system-admin" # DEPRECATED # "share_server:reset_status":"rule:admin_api" has been deprecated # since W in favor of "share_server:reset_status":"rule:system-admin". # The share server API now supports system scope and default roles. # Migrates a share server to the specified host. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:share_server_migration_start": "rule:system-admin" # DEPRECATED # "share_server:share_server_migration_start":"rule:admin_api" has # been deprecated since W in favor of # "share_server:share_server_migration_start":"rule:system-admin". # The share server API now supports system scope and default roles. # Check if can migrates a share server to the specified host. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:share_server_migration_check": "rule:system-reader" # DEPRECATED # "share_server:share_server_migration_check":"rule:admin_api" has # been deprecated since W in favor of # "share_server:share_server_migration_check":"rule:system-reader". # The share server API now supports system scope and default roles. # Invokes the 2nd phase of share server migration. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:share_server_migration_complete": "rule:system-admin" # DEPRECATED # "share_server:share_server_migration_complete":"rule:admin_api" has # been deprecated since W in favor of # "share_server:share_server_migration_complete":"rule:system-admin". # The share server API now supports system scope and default roles. # Attempts to cancel share server migration. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:share_server_migration_cancel": "rule:system-admin" # DEPRECATED # "share_server:share_server_migration_cancel":"rule:admin_api" has # been deprecated since W in favor of # "share_server:share_server_migration_cancel":"rule:system-admin". # The share server API now supports system scope and default roles. # Retrieves the share server migration progress for a given share # server. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:share_server_migration_get_progress": "rule:system-reader" # DEPRECATED # "share_server:share_server_migration_get_progress":"rule:admin_api" # has been deprecated since W in favor of # "share_server:share_server_migration_get_progress":"rule:system- # reader". # The share server API now supports system scope and default roles. # Resets task state. # POST /share-servers/{share_server_id}/action # Intended scope(s): system #"share_server:share_server_reset_task_state": "rule:system-admin" # DEPRECATED # "share_server:share_server_reset_task_state":"rule:admin_api" has # been deprecated since W in favor of # "share_server:share_server_reset_task_state":"rule:system-admin". # The share server API now supports system scope and default roles. # Return a list of all running services. # GET /os-services # GET /os-services?{query} # GET /services # GET /services?{query} # Intended scope(s): system #"service:index": "rule:system-reader" # DEPRECATED # "service:index":"rule:admin_api" has been deprecated since W in # favor of "service:index":"rule:system-reader". # The service API now supports system scope and default roles. # Enable/Disable scheduling for a service. # PUT /os-services/disable # PUT /os-services/enable # PUT /services/disable # PUT /services/enable # Intended scope(s): system #"service:update": "rule:system-admin" # DEPRECATED # "service:update":"rule:admin_api" has been deprecated since W in # favor of "service:update":"rule:system-admin". # The service API now supports system scope and default roles. # Update the quotas for a project/user and/or share type. # PUT /quota-sets/{tenant_id} # PUT /quota-sets/{tenant_id}?user_id={user_id} # PUT /quota-sets/{tenant_id}?share_type={share_type_id} # PUT /os-quota-sets/{tenant_id} # PUT /os-quota-sets/{tenant_id}?user_id={user_id} # Intended scope(s): system #"quota_set:update": "rule:system-admin" # DEPRECATED # "quota_set:update":"rule:admin_api" has been deprecated since W in # favor of "quota_set:update":"rule:system-admin". # The quota API now supports system scope and default roles. # List the quotas for a tenant/user. # GET /quota-sets/{tenant_id}/defaults # GET /os-quota-sets/{tenant_id}/defaults # Intended scope(s): system, project #"quota_set:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "quota_set:show":"rule:default" has been deprecated since W in favor # of "quota_set:show":"(rule:system-reader) or (rule:project-reader)". # The quota API now supports system scope and default roles. # Delete quota for a tenant/user or tenant/share-type. The quota will # revert back to default (Admin only). # DELETE /quota-sets/{tenant_id} # DELETE /quota-sets/{tenant_id}?user_id={user_id} # DELETE /quota-sets/{tenant_id}?share_type={share_type_id} # DELETE /os-quota-sets/{tenant_id} # DELETE /os-quota-sets/{tenant_id}?user_id={user_id} # Intended scope(s): system #"quota_set:delete": "rule:system-admin" # DEPRECATED # "quota_set:delete":"rule:admin_api" has been deprecated since W in # favor of "quota_set:delete":"rule:system-admin". # The quota API now supports system scope and default roles. # Update quota class. # PUT /quota-class-sets/{class_name} # PUT /os-quota-class-sets/{class_name} # Intended scope(s): system #"quota_class_set:update": "rule:system-admin" # DEPRECATED # "quota_class_set:update":"rule:admin_api" has been deprecated since # W in favor of "quota_class_set:update":"rule:system-admin". # The quota class API now supports system scope and default roles. # Get quota class. # GET /quota-class-sets/{class_name} # GET /os-quota-class-sets/{class_name} # Intended scope(s): system, project #"quota_class_set:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "quota_class_set:show":"rule:default" has been deprecated since W in # favor of "quota_class_set:show":"(rule:system-reader) or # (rule:project-reader)". # The quota class API now supports system scope and default roles. # Create share group type specs. # POST /share-group-types/{share_group_type_id}/group-specs # Intended scope(s): system #"share_group_types_spec:create": "rule:system-admin" # DEPRECATED # "share_group_types_spec:create":"rule:admin_api" has been deprecated # since W in favor of "share_group_types_spec:create":"rule:system- # admin". # The share group type specs API now support system scope and default # roles. # Get share group type specs. # GET /share-group-types/{share_group_type_id}/group-specs # Intended scope(s): system #"share_group_types_spec:index": "rule:system-reader" # DEPRECATED # "share_group_types_spec:index":"rule:admin_api" has been deprecated # since W in favor of "share_group_types_spec:index":"rule:system- # reader". # The share group type specs API now support system scope and default # roles. # Get details of a share group type spec. # GET /share-group-types/{share_group_type_id}/group-specs/{key} # Intended scope(s): system #"share_group_types_spec:show": "rule:system-reader" # DEPRECATED # "share_group_types_spec:show":"rule:admin_api" has been deprecated # since W in favor of "share_group_types_spec:show":"rule:system- # reader". # The share group type specs API now support system scope and default # roles. # Update a share group type spec. # PUT /share-group-types/{share_group_type_id}/group-specs/{key} # Intended scope(s): system #"share_group_types_spec:update": "rule:system-admin" # DEPRECATED # "share_group_types_spec:update":"rule:admin_api" has been deprecated # since W in favor of "share_group_types_spec:update":"rule:system- # admin". # The share group type specs API now support system scope and default # roles. # Delete a share group type spec. # DELETE /share-group-types/{share_group_type_id}/group-specs/{key} # Intended scope(s): system #"share_group_types_spec:delete": "rule:system-admin" # DEPRECATED # "share_group_types_spec:delete":"rule:admin_api" has been deprecated # since W in favor of "share_group_types_spec:delete":"rule:system- # admin". # The share group type specs API now support system scope and default # roles. # Create a new share group type. # POST /share-group-types # Intended scope(s): system #"share_group_type:create": "rule:system-admin" # DEPRECATED # "share_group_type:create":"rule:admin_api" has been deprecated since # W in favor of "share_group_type:create":"rule:system-admin". # The share group type API now supports system scope and default # roles. # Get the list of share group types. # GET /share-group-types # GET /share-group-types?is_public=all # Intended scope(s): system, project #"share_group_type:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group_type:index":"rule:default" has been deprecated since W # in favor of "share_group_type:index":"(rule:system-reader) or # (rule:project-reader)". # The share group type API now supports system scope and default # roles. # Get details regarding the specified share group type. # GET /share-group-types/{share_group_type_id} # Intended scope(s): system, project #"share_group_type:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group_type:show":"rule:default" has been deprecated since W # in favor of "share_group_type:show":"(rule:system-reader) or # (rule:project-reader)". # The share group type API now supports system scope and default # roles. # Get the default share group type. # GET /share-group-types/default # Intended scope(s): system, project #"share_group_type:default": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group_type:default":"rule:default" has been deprecated since # W in favor of "share_group_type:default":"(rule:system-reader) or # (rule:project-reader)". # The share group type API now supports system scope and default # roles. # Delete an existing group type. # DELETE /share-group-types/{share_group_type_id} # Intended scope(s): system #"share_group_type:delete": "rule:system-admin" # DEPRECATED # "share_group_type:delete":"rule:admin_api" has been deprecated since # W in favor of "share_group_type:delete":"rule:system-admin". # The share group type API now supports system scope and default # roles. # Get project access by share group type. # GET /share-group-types/{share_group_type_id}/access # Intended scope(s): system #"share_group_type:list_project_access": "rule:system-reader" # DEPRECATED # "share_group_type:list_project_access":"rule:admin_api" has been # deprecated since W in favor of # "share_group_type:list_project_access":"rule:system-reader". # The share group type API now supports system scope and default # roles. # Allow project to use the share group type. # POST /share-group-types/{share_group_type_id}/action # Intended scope(s): system #"share_group_type:add_project_access": "rule:system-admin" # DEPRECATED # "share_group_type:add_project_access":"rule:admin_api" has been # deprecated since W in favor of # "share_group_type:add_project_access":"rule:system-admin". # The share group type API now supports system scope and default # roles. # Deny project access to use the share group type. # POST /share-group-types/{share_group_type_id}/action # Intended scope(s): system #"share_group_type:remove_project_access": "rule:system-admin" # DEPRECATED # "share_group_type:remove_project_access":"rule:admin_api" has been # deprecated since W in favor of # "share_group_type:remove_project_access":"rule:system-admin". # The share group type API now supports system scope and default # roles. # Create a new share group snapshot. # POST /share-group-snapshots # Intended scope(s): system, project #"share_group_snapshot:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_group_snapshot:create":"rule:default" has been deprecated # since W in favor of "share_group_snapshot:create":"(rule:system- # admin) or (rule:project-member)". # The share group snapshots API now supports system scope and default # roles. # Get details of a share group snapshot. # GET /share-group-snapshots/{share_group_snapshot_id} # Intended scope(s): system, project #"share_group_snapshot:get": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group_snapshot:get":"rule:default" has been deprecated since # W in favor of "share_group_snapshot:get":"(rule:system-reader) or # (rule:project-reader)". # The share group snapshots API now supports system scope and default # roles. # Get all share group snapshots. # GET /share-group-snapshots # GET /share-group-snapshots/detail # GET /share-group-snapshots/{query} # GET /share-group-snapshots/detail?{query} # Intended scope(s): system, project #"share_group_snapshot:get_all": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group_snapshot:get_all":"rule:default" has been deprecated # since W in favor of "share_group_snapshot:get_all":"(rule:system- # reader) or (rule:project-reader)". # The share group snapshots API now supports system scope and default # roles. # Update a share group snapshot. # PUT /share-group-snapshots/{share_group_snapshot_id} # Intended scope(s): system, project #"share_group_snapshot:update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_group_snapshot:update":"rule:default" has been deprecated # since W in favor of "share_group_snapshot:update":"(rule:system- # admin) or (rule:project-member)". # The share group snapshots API now supports system scope and default # roles. # Delete a share group snapshot. # DELETE /share-group-snapshots/{share_group_snapshot_id} # Intended scope(s): system, project #"share_group_snapshot:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_group_snapshot:delete":"rule:default" has been deprecated # since W in favor of "share_group_snapshot:delete":"(rule:system- # admin) or (rule:project-member)". # The share group snapshots API now supports system scope and default # roles. # Force delete a share group snapshot. # POST /share-group-snapshots/{share_group_snapshot_id}/action # Intended scope(s): system, project #"share_group_snapshot:force_delete": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_group_snapshot:force_delete":"rule:admin_api" has been # deprecated since W in favor of # "share_group_snapshot:force_delete":"(rule:system-admin) or # (rule:project-admin)". # The share group snapshots API now supports system scope and default # roles. # Reset a share group snapshot's status. # POST /share-group-snapshots/{share_group_snapshot_id}/action # Intended scope(s): system, project #"share_group_snapshot:reset_status": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_group_snapshot:reset_status":"rule:admin_api" has been # deprecated since W in favor of # "share_group_snapshot:reset_status":"(rule:system-admin) or # (rule:project-admin)". # The share group snapshots API now supports system scope and default # roles. # Create share group. # POST /share-groups # Intended scope(s): system, project #"share_group:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_group:create":"rule:default" has been deprecated since W in # favor of "share_group:create":"(rule:system-admin) or (rule:project- # member)". # The share group API now supports system scope and default roles. # Get details of a share group. # GET /share-groups/{share_group_id} # Intended scope(s): system, project #"share_group:get": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group:get":"rule:default" has been deprecated since W in # favor of "share_group:get":"(rule:system-reader) or (rule:project- # reader)". # The share group API now supports system scope and default roles. # Get all share groups. # GET /share-groups # GET /share-groups/detail # GET /share-groups?{query} # GET /share-groups/detail?{query} # Intended scope(s): system, project #"share_group:get_all": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_group:get_all":"rule:default" has been deprecated since W in # favor of "share_group:get_all":"(rule:system-reader) or # (rule:project-reader)". # The share group API now supports system scope and default roles. # Update share group. # PUT /share-groups/{share_group_id} # Intended scope(s): system, project #"share_group:update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_group:update":"rule:default" has been deprecated since W in # favor of "share_group:update":"(rule:system-admin) or (rule:project- # member)". # The share group API now supports system scope and default roles. # Delete share group. # DELETE /share-groups/{share_group_id} # Intended scope(s): system, project #"share_group:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_group:delete":"rule:default" has been deprecated since W in # favor of "share_group:delete":"(rule:system-admin) or (rule:project- # member)". # The share group API now supports system scope and default roles. # Force delete a share group. # POST /share-groups/{share_group_id}/action # Intended scope(s): system, project #"share_group:force_delete": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_group:force_delete":"rule:admin_api" has been deprecated # since W in favor of "share_group:force_delete":"(rule:system-admin) # or (rule:project-admin)". # The share group API now supports system scope and default roles. # Reset share group's status. # POST /share-groups/{share_group_id}/action # Intended scope(s): system, project #"share_group:reset_status": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_group:reset_status":"rule:admin_api" has been deprecated # since W in favor of "share_group:reset_status":"(rule:system-admin) # or (rule:project-admin)". # The share group API now supports system scope and default roles. # Create share replica. # POST /share-replicas # Intended scope(s): system, project #"share_replica:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_replica:create":"rule:default" has been deprecated since W in # favor of "share_replica:create":"(rule:system-admin) or # (rule:project-member)". # The share replica API now supports system scope and default roles. # Get all share replicas. # GET /share-replicas # GET /share-replicas/detail # GET /share-replicas/detail?share_id={share_id} # Intended scope(s): system, project #"share_replica:get_all": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_replica:get_all":"rule:default" has been deprecated since W # in favor of "share_replica:get_all":"(rule:system-reader) or # (rule:project-reader)". # The share replica API now supports system scope and default roles. # Get details of a share replica. # GET /share-replicas/{share_replica_id} # Intended scope(s): system, project #"share_replica:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_replica:show":"rule:default" has been deprecated since W in # favor of "share_replica:show":"(rule:system-reader) or # (rule:project-reader)". # The share replica API now supports system scope and default roles. # Delete a share replica. # DELETE /share-replicas/{share_replica_id} # Intended scope(s): system, project #"share_replica:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_replica:delete":"rule:default" has been deprecated since W in # favor of "share_replica:delete":"(rule:system-admin) or # (rule:project-member)". # The share replica API now supports system scope and default roles. # Force delete a share replica. # POST /share-replicas/{share_replica_id}/action # Intended scope(s): system, project #"share_replica:force_delete": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_replica:force_delete":"rule:admin_api" has been deprecated # since W in favor of "share_replica:force_delete":"(rule:system- # admin) or (rule:project-admin)". # The share replica API now supports system scope and default roles. # Promote a non-active share replica to active. # POST /share-replicas/{share_replica_id}/action # Intended scope(s): system, project #"share_replica:promote": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_replica:promote":"rule:default" has been deprecated since W # in favor of "share_replica:promote":"(rule:system-admin) or # (rule:project-member)". # The share replica API now supports system scope and default roles. # Resync a share replica that is out of sync. # POST /share-replicas/{share_replica_id}/action # Intended scope(s): system, project #"share_replica:resync": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_replica:resync":"rule:admin_api" has been deprecated since W # in favor of "share_replica:resync":"(rule:system-admin) or # (rule:project-admin)". # The share replica API now supports system scope and default roles. # Reset share replica's replica_state attribute. # POST /share-replicas/{share_replica_id}/action # Intended scope(s): system, project #"share_replica:reset_replica_state": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_replica:reset_replica_state":"rule:admin_api" has been # deprecated since W in favor of # "share_replica:reset_replica_state":"(rule:system-admin) or # (rule:project-admin)". # The share replica API now supports system scope and default roles. # Reset share replica's status. # POST /share-replicas/{share_replica_id}/action # Intended scope(s): system, project #"share_replica:reset_status": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_replica:reset_status":"rule:admin_api" has been deprecated # since W in favor of "share_replica:reset_status":"(rule:system- # admin) or (rule:project-admin)". # The share replica API now supports system scope and default roles. # Get all export locations of a given share replica. # GET /share-replicas/{share_replica_id}/export-locations # Intended scope(s): system, project #"share_replica_export_location:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_replica_export_location:index":"rule:default" has been # deprecated since W in favor of # "share_replica_export_location:index":"(rule:system-reader) or # (rule:project-reader)". # The share replica export location API now supports system scope and # default roles. # Get details about the requested share replica export location. # GET /share-replicas/{share_replica_id}/export-locations/{export_location_id} # Intended scope(s): system, project #"share_replica_export_location:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_replica_export_location:show":"rule:default" has been # deprecated since W in favor of # "share_replica_export_location:show":"(rule:system-reader) or # (rule:project-reader)". # The share replica export location API now supports system scope and # default roles. # Create share network. # POST /share-networks # Intended scope(s): system, project #"share_network:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:create":"rule:default" has been deprecated since W in # favor of "share_network:create":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Get details of a share network. # GET /share-networks/{share_network_id} # Intended scope(s): system, project #"share_network:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_network:show":"rule:default" has been deprecated since W in # favor of "share_network:show":"(rule:system-reader) or # (rule:project-reader)". # The share network API now support system scope and default roles. # Get all share networks. # GET /share-networks # GET /share-networks?{query} # Intended scope(s): system, project #"share_network:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_network:index":"rule:default" has been deprecated since W in # favor of "share_network:index":"(rule:system-reader) or # (rule:project-reader)". # The share network API now support system scope and default roles. # Get details of share networks . # GET /share-networks/detail?{query} # GET /share-networks/detail # Intended scope(s): system, project #"share_network:detail": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_network:detail":"rule:default" has been deprecated since W in # favor of "share_network:detail":"(rule:system-reader) or # (rule:project-reader)". # The share network API now support system scope and default roles. # Update a share network. # PUT /share-networks/{share_network_id} # Intended scope(s): system, project #"share_network:update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:update":"rule:default" has been deprecated since W in # favor of "share_network:update":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Delete a share network. # DELETE /share-networks/{share_network_id} # Intended scope(s): system, project #"share_network:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:delete":"rule:default" has been deprecated since W in # favor of "share_network:delete":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Add security service to share network. # POST /share-networks/{share_network_id}/action # Intended scope(s): system, project #"share_network:add_security_service": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:add_security_service":"rule:default" has been # deprecated since W in favor of # "share_network:add_security_service":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Check the feasibility of add security service to a share network. # POST /share-networks/{share_network_id}/action # Intended scope(s): system, project #"share_network:add_security_service_check": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:add_security_service_check":"rule:default" has been # deprecated since W in favor of # "share_network:add_security_service_check":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Remove security service from share network. # POST /share-networks/{share_network_id}/action # Intended scope(s): system, project #"share_network:remove_security_service": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:remove_security_service":"rule:default" has been # deprecated since W in favor of # "share_network:remove_security_service":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Update security service from share network. # POST /share-networks/{share_network_id}/action # Intended scope(s): system, project #"share_network:update_security_service": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:update_security_service":"rule:default" has been # deprecated since W in favor of # "share_network:update_security_service":"(rule:system-admin) or # (rule:project-member)". # The share network API now support system scope and default roles. # Check the feasibility of update a security service from share # network. # POST /share-networks/{share_network_id}/action # Intended scope(s): system, project #"share_network:update_security_service_check": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network:update_security_service_check":"rule:default" has # been deprecated since W in favor of # "share_network:update_security_service_check":"(rule:system-admin) # or (rule:project-member)". # The share network API now support system scope and default roles. # Reset share network`s status. # POST /share-networks/{share_network_id}/action # Intended scope(s): system, project #"share_network:reset_status": "(rule:system-admin) or (rule:project-admin)" # DEPRECATED # "share_network:reset_status":"rule:admin_api" has been deprecated # since W in favor of "share_network:reset_status":"(rule:system- # admin) or (rule:project-admin)". # The share network API now support system scope and default roles. # Get share networks belonging to all projects. # GET /share-networks?all_tenants=1 # GET /share-networks/detail?all_tenants=1 # Intended scope(s): system #"share_network:get_all_share_networks": "rule:system-reader" # DEPRECATED # "share_network:get_all_share_networks":"rule:admin_api" has been # deprecated since W in favor of # "share_network:get_all_share_networks":"rule:system-reader". # The share network API now support system scope and default roles. # Create a new share network subnet. # POST /share-networks/{share_network_id}/subnets # Intended scope(s): system, project #"share_network_subnet:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network_subnet:create":"rule:default" has been deprecated # since W in favor of "share_network_subnet:create":"(rule:system- # admin) or (rule:project-member)". # The share network subnet API now supports system scope and default # roles. # Delete a share network subnet. # DELETE /share-networks/{share_network_id}/subnets/{share_network_subnet_id} # Intended scope(s): system, project #"share_network_subnet:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_network_subnet:delete":"rule:default" has been deprecated # since W in favor of "share_network_subnet:delete":"(rule:system- # admin) or (rule:project-member)". # The share network subnet API now supports system scope and default # roles. # Shows a share network subnet. # GET /share-networks/{share_network_id}/subnets/{share_network_subnet_id} # Intended scope(s): system, project #"share_network_subnet:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_network_subnet:show":"rule:default" has been deprecated since # W in favor of "share_network_subnet:show":"(rule:system-reader) or # (rule:project-reader)". # The share network subnet API now supports system scope and default # roles. # Get all share network subnets. # GET /share-networks/{share_network_id}/subnets # Intended scope(s): system, project #"share_network_subnet:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_network_subnet:index":"rule:default" has been deprecated # since W in favor of "share_network_subnet:index":"(rule:system- # reader) or (rule:project-reader)". # The share network subnet API now supports system scope and default # roles. # Create security service. # POST /security-services # Intended scope(s): system, project #"security_service:create": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "security_service:create":"rule:default" has been deprecated since W # in favor of "security_service:create":"(rule:system-admin) or # (rule:project-member)". # The security service API now supports system scope and default # roles. # Get details of a security service. # GET /security-services/{security_service_id} # Intended scope(s): system, project #"security_service:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "security_service:show":"rule:default" has been deprecated since W # in favor of "security_service:show":"(rule:system-reader) or # (rule:project-reader)". # The security service API now supports system scope and default # roles. # Get details of all security services. # GET /security-services/detail?{query} # GET /security-services/detail # Intended scope(s): system, project #"security_service:detail": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "security_service:detail":"rule:default" has been deprecated since W # in favor of "security_service:detail":"(rule:system-reader) or # (rule:project-reader)". # The security service API now supports system scope and default # roles. # Get all security services. # GET /security-services # GET /security-services?{query} # Intended scope(s): system, project #"security_service:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "security_service:index":"rule:default" has been deprecated since W # in favor of "security_service:index":"(rule:system-reader) or # (rule:project-reader)". # The security service API now supports system scope and default # roles. # Update a security service. # PUT /security-services/{security_service_id} # Intended scope(s): system, project #"security_service:update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "security_service:update":"rule:default" has been deprecated since W # in favor of "security_service:update":"(rule:system-admin) or # (rule:project-member)". # The security service API now supports system scope and default # roles. # Delete a security service. # DELETE /security-services/{security_service_id} # Intended scope(s): system, project #"security_service:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "security_service:delete":"rule:default" has been deprecated since W # in favor of "security_service:delete":"(rule:system-admin) or # (rule:project-member)". # The security service API now supports system scope and default # roles. # Get security services of all projects. # GET /security-services?all_tenants=1 # GET /security-services/detail?all_tenants=1 # Intended scope(s): system #"security_service:get_all_security_services": "rule:system-reader" # DEPRECATED # "security_service:get_all_security_services":"rule:admin_api" has # been deprecated since W in favor of # "security_service:get_all_security_services":"rule:system-reader". # The security service API now supports system scope and default # roles. # Get all export locations of a given share. # GET /shares/{share_id}/export_locations # Intended scope(s): system, project #"share_export_location:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_export_location:index":"rule:default" has been deprecated # since W in favor of "share_export_location:index":"(rule:system- # reader) or (rule:project-reader)". # The share export location API now support system scope and default # roles. # Get details about the requested export location. # GET /shares/{share_id}/export_locations/{export_location_id} # Intended scope(s): system, project #"share_export_location:show": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_export_location:show":"rule:default" has been deprecated # since W in favor of "share_export_location:show":"(rule:system- # reader) or (rule:project-reader)". # The share export location API now support system scope and default # roles. # Get all share instances. # GET /share_instances # GET /share_instances?{query} # Intended scope(s): system #"share_instance:index": "rule:system-reader" # DEPRECATED # "share_instance:index":"rule:admin_api" has been deprecated since W # in favor of "share_instance:index":"rule:system-reader". # The share instances API now supports system scope and default roles. # Get details of a share instance. # GET /share_instances/{share_instance_id} # Intended scope(s): system #"share_instance:show": "rule:system-reader" # DEPRECATED # "share_instance:show":"rule:admin_api" has been deprecated since W # in favor of "share_instance:show":"rule:system-reader". # The share instances API now supports system scope and default roles. # Force delete a share instance. # POST /share_instances/{share_instance_id}/action # Intended scope(s): system #"share_instance:force_delete": "rule:system-admin" # DEPRECATED # "share_instance:force_delete":"rule:admin_api" has been deprecated # since W in favor of "share_instance:force_delete":"rule:system- # admin". # The share instances API now supports system scope and default roles. # Reset share instance's status. # POST /share_instances/{share_instance_id}/action # Intended scope(s): system #"share_instance:reset_status": "rule:system-admin" # DEPRECATED # "share_instance:reset_status":"rule:admin_api" has been deprecated # since W in favor of "share_instance:reset_status":"rule:system- # admin". # The share instances API now supports system scope and default roles. # Get details of a given message. # GET /messages/{message_id} # Intended scope(s): system, project #"message:get": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "message:get":"rule:default" has been deprecated since W in favor of # "message:get":"(rule:system-reader) or (rule:project-reader)". # The messages API now supports system scope and default roles. # Get all messages. # GET /messages # GET /messages?{query} # Intended scope(s): system, project #"message:get_all": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "message:get_all":"rule:default" has been deprecated since W in # favor of "message:get_all":"(rule:system-reader) or (rule:project- # reader)". # The messages API now supports system scope and default roles. # Delete a message. # DELETE /messages/{message_id} # Intended scope(s): system, project #"message:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "message:delete":"rule:default" has been deprecated since W in favor # of "message:delete":"(rule:system-admin) or (rule:project-member)". # The messages API now supports system scope and default roles. # Get details of a share access rule. # GET /share-access-rules/{share_access_id} # Intended scope(s): system, project #"share_access_rule:get": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_access_rule:get":"rule:default" has been deprecated since W # in favor of "share_access_rule:get":"(rule:system-reader) or # (rule:project-reader)". # The share access rule API now supports system scope and default # roles. # List access rules of a given share. # GET /share-access-rules?share_id={share_id}&key1=value1&key2=value2 # Intended scope(s): system, project #"share_access_rule:index": "(rule:system-reader) or (rule:project-reader)" # DEPRECATED # "share_access_rule:index":"rule:default" has been deprecated since W # in favor of "share_access_rule:index":"(rule:system-reader) or # (rule:project-reader)". # The share access rule API now supports system scope and default # roles. # Set metadata for a share access rule. # PUT /share-access-rules/{share_access_id}/metadata # Intended scope(s): system, project #"share_access_metadata:update": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_access_metadata:update":"rule:default" has been deprecated # since W in favor of "share_access_metadata:update":"(rule:system- # admin) or (rule:project-member)". # The share access metadata API now support system scope and default # roles. # Delete metadata for a share access rule. # DELETE /share-access-rules/{share_access_id}/metadata/{key} # Intended scope(s): system, project #"share_access_metadata:delete": "(rule:system-admin) or (rule:project-member)" # DEPRECATED # "share_access_metadata:delete":"rule:default" has been deprecated # since W in favor of "share_access_metadata:delete":"(rule:system- # admin) or (rule:project-member)". # The share access metadata API now support system scope and default # roles. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/dashboards/0000775000175000017500000000000000000000000017540 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/__init__.py0000664000175000017500000000000000000000000021637 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/dashboards/admin/0000775000175000017500000000000000000000000020630 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/__init__.py0000664000175000017500000000000000000000000022727 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui/dashboards/admin/defaults/0000775000175000017500000000000000000000000022437 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/defaults/__init__.py0000664000175000017500000000000000000000000024536 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/defaults/tables.py0000664000175000017500000000343600000000000024271 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tables from openstack_dashboard.dashboards.admin.defaults import tables as default_tbl MANILA_QUOTA_NAMES = { 'shares': _('Shares'), 'gigabytes': _('Share gigabytes'), 'snapshots': _('Share Snapshots'), 'snapshot_gigabytes': _('Share Snapshot gigabytes'), 'share_networks': _('Share Networks'), "share_groups": _('Share Groups'), "share_group_snapshots": _('Share Group Snapshots'), } def get_quota_name(quota): return MANILA_QUOTA_NAMES.get(quota.name, quota.name.replace("_", " ").title()) class UpdateDefaultShareQuotas(default_tbl.UpdateDefaultQuotas): name = 'update_share_defaults' step = 'update_default_share_quotas' class ShareQuotasTable(tables.DataTable): name = tables.Column(get_quota_name, verbose_name=_('Quota Name')) limit = tables.Column("limit", verbose_name=_('Limit')) def get_object_id(self, obj): return obj.name class Meta(object): name = "share_quotas" verbose_name = _("Shared Quotas") table_actions = (default_tbl.QuotaFilterAction, UpdateDefaultShareQuotas) multi_select = False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/defaults/tabs.py0000664000175000017500000000274200000000000023747 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tabs from openstack_dashboard import api from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin.defaults import tables class ShareQuotasTab(tabs.TableTab): table_classes = (tables.ShareQuotasTable,) name = _("Share Quotas") slug = "shared_quotas" template_name = ("horizon/common/_detail_table.html") def get_share_quotas_data(self): request = self.tab_group.request tenant_id = request.user.tenant_id try: data = api_manila.default_quota_get(request, tenant_id) except Exception: data = [] exceptions.handle(self.request, _('Unable to get manila default quota.')) return data def allowed(self, request): return api.base.is_service_enabled(request, 'share') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/defaults/workflows.py0000664000175000017500000000733200000000000025053 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import workflows from openstack_dashboard.api import base from manila_ui.api import manila as api_manila class UpdateDefaultShareQuotasAction(workflows.Action): shares = forms.IntegerField(min_value=-1, label=_("Shares")) share_gigabytes = forms.IntegerField( min_value=-1, label=_("Share gigabytes")) share_snapshots = forms.IntegerField( min_value=-1, label=_("Share snapshots")) share_snapshot_gigabytes = forms.IntegerField( min_value=-1, label=_("Share snapshot gigabytes")) share_networks = forms.IntegerField( min_value=-1, label=_("Share Networks")) # Share group quotas are missing here because default quota update # for share groups is not possible yet, see LP #1871252 def __init__(self, request, context, *args, **kwargs): super(UpdateDefaultShareQuotasAction, self).__init__( request, context, *args, **kwargs) disabled_quotas = context['disabled_quotas'] for field in disabled_quotas: if field in self.fields: self.fields[field].required = False self.fields[field].widget = forms.HiddenInput() def handle(self, request, data): try: if base.is_service_enabled(request, 'share'): manila_data = {} # Share group quotas are removed here because default # quota update for share groups is not possible yet, see # LP #1871252 allowed_updates = ( api_manila.MANILA_QUOTA_FIELDS - {'share_groups', 'share_group_snapshots'} ) for key in allowed_updates: manila_data[key] = data[key] api_manila.default_quota_update(request, **manila_data) return True except Exception: exceptions.handle(request, _('Unable to update default quotas.')) return False class Meta(object): name = _("Share") slug = 'update_default_share_quotas' help_text = _("From here you can update the default share quotas " "(max limits).") class UpdateDefaultShareQuotasStep(workflows.Step): action_class = UpdateDefaultShareQuotasAction contributes = api_manila.MANILA_QUOTA_FIELDS depends_on = ('disabled_quotas',) def prepare_action_context(self, request, context): try: quota_defaults = api_manila.default_quota_get( request, request.user.tenant_id) for field in api_manila.MANILA_QUOTA_FIELDS: # Resolve mismatch UI field names and data field names. data_field = api_manila.MANILA_QUOTA_FIELDS_DATA_MAP[field] context[field] = quota_defaults.get(data_field).limit except Exception: exceptions.handle(request, _('Unable to retrieve default share quotas.')) return context def allowed(self, request): return base.is_service_enabled(request, 'share') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7946513 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/0000775000175000017500000000000000000000000024402 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/__init__.py0000664000175000017500000000000000000000000026501 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/panel.py0000664000175000017500000000166700000000000026065 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class SecurityServices(horizon.Panel): name = _("Security Services") slug = 'security_services' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(SecurityServices) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/tables.py0000664000175000017500000000455700000000000026241 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import tables from manila_ui.api import manila class DeleteSecurityService(tables.DeleteAction): policy_rules = (("share", "security_service:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Security Service", u"Delete Security Services", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Security Service", u"Deleted Security Services", count ) def delete(self, request, obj_id): manila.security_service_delete(request, obj_id) class SecurityServicesTable(tables.DataTable): name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:admin:security_services:security_service_detail") description = tables.Column("description", verbose_name=_("Description")) project = tables.Column("project_name", verbose_name=_("Project")) dns_ip = tables.Column("dns_ip", verbose_name=_("DNS IP")) ou = tables.Column("ou", verbose_name=_("Organizational Unit")) server = tables.Column("server", verbose_name=_("Server")) domain = tables.Column("domain", verbose_name=_("Domain")) user = tables.Column("user", verbose_name=_("Sid")) def get_object_display(self, security_service): return security_service.name def get_object_id(self, security_service): return str(security_service.id) class Meta(object): name = "security_services" verbose_name = _("Security Services") table_actions = ( tables.NameFilterAction, DeleteSecurityService, ) row_actions = ( DeleteSecurityService, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/tabs.py0000664000175000017500000000215300000000000025706 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class SecurityServiceOverviewTab(tabs.Tab): name = _("Security Service Overview") slug = "security_service_overview_tab" template_name = "admin/security_services/_detail.html" def get_context_data(self, request): return {"sec_service": self.tab_group.kwargs["sec_service"]} class SecurityServiceDetailTabs(tabs.TabGroup): slug = "security_service_details" tabs = ( SecurityServiceOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/0000775000175000017500000000000000000000000026400 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7946513 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/security_services/0000775000175000017500000000000000000000000032152 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/security_services/_detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/security_services/_detail.ht0000664000175000017500000000214000000000000034105 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Security Service Overview" %}


{% trans "Type" %}
{{ sec_service.type }}
{% trans "Name" %}
{{ sec_service.name }}
{% trans "ID" %}
{{ sec_service.id }}
{% if sec_service.description %}
{% trans "Description" %}
{{ sec_service.description }}
{% endif %}
{% trans "Created at" %}
{{ sec_service.created_at|parse_date }}

{% trans "Security Service Details" %}


{% trans "DNS IP" %}
{{ sec_service.dns_ip }}
{% trans "Organizational Unit" %}
{{ sec_service.ou }}
{% trans "Server" %}
{{ sec_service.server }}
{% trans "Domain" %}
{{ sec_service.domain }}
{% trans "User" %}
{{ sec_service.user }}
././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/security_services/detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/security_services/detail.htm0000664000175000017500000000034600000000000034131 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Security Service Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/templates/security_services/index.html0000664000175000017500000000035500000000000034152 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Security Services" %}{% endblock %} {% block main %}
{{ security_services_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/urls.py0000664000175000017500000000161000000000000025737 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.security_services import views urlpatterns = [ re_path( r'^$', views.SecurityServicesView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.SecurityServiceDetailView.as_view(), name='security_service_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/security_services/views.py0000664000175000017500000000404400000000000026113 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Admin views for managing security services. """ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon.utils import memoized from manila_ui.api import manila import manila_ui.dashboards.admin.security_services.tables as ss_tables import manila_ui.dashboards.admin.security_services.tabs as ss_tabs from manila_ui.dashboards.admin import utils import manila_ui.dashboards.project.security_services.views as ss_views class SecurityServicesView(tables.MultiTableView): table_classes = ( ss_tables.SecurityServicesTable, ) template_name = "admin/security_services/index.html" page_title = _("Security Services") @memoized.memoized_method def get_security_services_data(self): try: security_services = manila.security_service_list( self.request, search_opts={'all_tenants': True}) utils.set_project_name_to_objects(self.request, security_services) except Exception: security_services = [] exceptions.handle( self.request, _("Unable to retrieve security services")) return security_services class SecurityServiceDetailView(ss_views.Detail): tab_group_class = ss_tabs.SecurityServiceDetailTabs template_name = "admin/security_services/detail.html" redirect_url = reverse_lazy('horizon:admin:security_services:index') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7946513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/0000775000175000017500000000000000000000000025250 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/__init__.py0000664000175000017500000000000000000000000027347 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/forms.py0000664000175000017500000000371700000000000026760 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class ResetShareGroupSnapshotStatusForm(forms.SelfHandlingForm): status = forms.ChoiceField( label=_("Status"), required=True, choices=( ('available', 'available'), ('error', 'error'), ) ) def handle(self, request, data): s_id = self.initial['share_group_snapshot_id'] try: manila.share_group_snapshot_reset_state( request, s_id, data["status"]) message = _( "Reseting share group snapshot ('%(id)s') status " "from '%(from)s' to '%(to)s'.") % { "id": self.initial['share_group_snapshot_name'] or s_id, "from": self.initial['share_group_snapshot_status'], "to": data["status"]} messages.success(request, message) return True except Exception: redirect = reverse("horizon:admin:share_group_snapshots:index") exceptions.handle( request, _("Unable to reset status of share group snapshot " "'%s'.") % s_id, redirect=redirect) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/panel.py0000664000175000017500000000173200000000000026724 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareGroupSnapshots(horizon.Panel): name = _("Share Group Snapshots") slug = 'share_group_snapshots' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareGroupSnapshots) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/tables.py0000664000175000017500000001070100000000000027073 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.template.defaultfilters import title from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import exceptions from horizon import tables from horizon.utils import filters from manila_ui.api import manila class ShareGroupSnapshotShareGroupNameColumn(tables.Column): def get_link_url(self, snapshot): return reverse(self.link, args=(snapshot.share_group_id,)) class DeleteShareGroupSnapshot(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Group Snapshot", u"Delete Share Group Snapshots", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Group Snapshot", u"Deleted Share Group Snapshots", count ) def delete(self, request, obj_id): obj = self.table.get_object_by_id(obj_id) name = self.table.get_object_display(obj) try: manila.share_group_snapshot_delete(request, obj_id) except Exception: msg = _('Unable to delete share group snapshot "%s". ' 'One or more share groups depend on it.') exceptions.handle(self.request, msg % name) raise def allowed(self, request, snapshot=None): if snapshot: return snapshot.status.lower() in ('available', 'error') return True class ResetShareGroupSnapshotStatus(tables.LinkAction): name = "reset_share_group_snapshot_status" verbose_name = _("Reset status") url = "horizon:admin:share_group_snapshots:reset_status" classes = ("ajax-modal", "btn-create") def allowed(self, request, share_group=None): return True class UpdateShareGroupSnapshotRow(tables.Row): ajax = True def get_data(self, request, share_group_snapshot_id): snapshot = manila.share_group_snapshot_get( request, share_group_snapshot_id) if not snapshot.name: snapshot.name = share_group_snapshot_id return snapshot class ShareGroupSnapshotsTable(tables.DataTable): STATUS_CHOICES = ( ("available", True), ("creating", None), ("error", False), ) STATUS_DISPLAY_CHOICES = ( ("available", pgettext_lazy("Current status of snapshot", u"Available")), ("creating", pgettext_lazy("Current status of snapshot", u"Creating")), ("error", pgettext_lazy("Current status of snapshot", u"Error")), ) name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:admin:share_group_snapshots:detail") description = tables.Column( "description", verbose_name=_("Description"), truncate=40) created_at = tables.Column( "created_at", verbose_name=_("Created at"), filters=( filters.parse_isotime, )) status = tables.Column( "status", filters=(title,), verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) source = ShareGroupSnapshotShareGroupNameColumn( "share_group", verbose_name=_("Source"), link="horizon:admin:share_groups:detail") def get_object_display(self, obj): return obj.name class Meta(object): name = "share_group_snapshots" verbose_name = _("Share Group Snapshots") status_columns = ["status"] row_class = UpdateShareGroupSnapshotRow table_actions = ( tables.NameFilterAction, DeleteShareGroupSnapshot, ) row_actions = ( ResetShareGroupSnapshotStatus, DeleteShareGroupSnapshot, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/tabs.py0000664000175000017500000000227200000000000026556 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareGroupSnapshotOverviewTab(tabs.Tab): name = _("Share Group Snapshot Overview") slug = "share_group_snapshot_overview_tab" template_name = "admin/share_group_snapshots/_detail.html" def get_context_data(self, request): return {"share_group_snapshot": self.tab_group.kwargs[ "share_group_snapshot"]} class ShareGroupSnapshotDetailTabs(tabs.TabGroup): slug = "share_group_snapshot_details" tabs = ( ShareGroupSnapshotOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/0000775000175000017500000000000000000000000027246 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7946513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/0000775000175000017500000000000000000000000033666 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000021600000000000011454 xustar0000000000000000120 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/_detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/_d0000664000175000017500000000160100000000000034171 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Group Snapshot Overview" %}


{% trans "Name" %}
{{ share_group_snapshot.name }}
{% trans "ID" %}
{{ share_group_snapshot.id }}
{% url 'horizon:admin:share_groups:detail' share_group_snapshot.share_group_id as sg_url %}
{% trans "Source Share Group" %}
{{ share_group_snapshot.sg_name_or_id }}
{% if share_group_snapshot.description %}
{% trans "Description" %}
{{ share_group_snapshot.description }}
{% endif %}
{% trans "Status" %}
{{ share_group_snapshot.status|capfirst }}
{% trans "Created" %}
{{ share_group_snapshot.created_at|parse_date }}
././@PaxHeader0000000000000000000000000000022400000000000011453 xustar0000000000000000126 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/_reset_status.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/_r0000664000175000017500000000031000000000000034203 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

"Reset status of '{{ share_group_snapshot_name }}' share group snapshot."

{% endblock %} ././@PaxHeader0000000000000000000000000000021500000000000011453 xustar0000000000000000119 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/de0000664000175000017500000000035200000000000034201 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Snapshot Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/index.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/in0000664000175000017500000000036500000000000034223 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Snapshots" %}{% endblock %} {% block main %}
{{ share_group_snapshots_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000022300000000000011452 xustar0000000000000000125 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/reset_status.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/re0000664000175000017500000000033500000000000034220 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Reset Share Group Snapshot Status" %}{% endblock %} {% block main %} {% include 'admin/share_group_snapshots/_reset_status.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/urls.py0000664000175000017500000000234600000000000026614 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.urls import re_path from manila_ui.dashboards.admin.share_group_snapshots import views from manila_ui import features if features.is_share_groups_enabled(): urlpatterns = [ re_path( r'^$', views.ShareGroupSnapshotsView.as_view(), name='index'), re_path( r'^(?P[^/]+)/$', views.ShareGroupSnapshotDetailView.as_view(), name='detail'), re_path( r'^(?P[^/]+)/reset_status$', views.ResetShareGroupSnapshotStatusView.as_view(), name='reset_status'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_snapshots/views.py0000664000175000017500000001312100000000000026755 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. """ Admin views for managing share group snapshots. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila import manila_ui.dashboards.admin.share_group_snapshots.forms as sgs_forms import manila_ui.dashboards.admin.share_group_snapshots.tables as sgs_tables import manila_ui.dashboards.admin.share_group_snapshots.tabs as sgs_tabs class ShareGroupSnapshotsView(tables.MultiTableView): table_classes = ( sgs_tables.ShareGroupSnapshotsTable, ) template_name = "admin/share_group_snapshots/index.html" page_title = _("Share Group Snapshots") @memoized.memoized_method def get_share_group_snapshots_data(self): share_group_snapshots = [] try: share_group_snapshots = manila.share_group_snapshot_list( self.request, search_opts={'all_tenants': True}) share_groups = manila.share_group_list(self.request) sg_names = dict([(sg.id, sg.name or sg.id) for sg in share_groups]) for snapshot in share_group_snapshots: snapshot.share_group = sg_names.get(snapshot.share_group_id) except Exception: msg = _("Unable to retrieve share group snapshot list.") exceptions.handle(self.request, msg) return share_group_snapshots class ShareGroupSnapshotDetailView(tabs.TabView): tab_group_class = sgs_tabs.ShareGroupSnapshotDetailTabs template_name = "admin/share_group_snapshots/detail.html" redirect_url = reverse_lazy("horizon:admin:share_group_snapshots:index") def get_context_data(self, **kwargs): context = super(ShareGroupSnapshotDetailView, self).get_context_data( **kwargs) snapshot = self.get_data() snapshot_display_name = snapshot.name or snapshot.id context["snapshot"] = snapshot context["snapshot_display_name"] = snapshot_display_name context["page_title"] = _( "Share Group Snapshot Details: %(sgs_display_name)s") % ( {'sgs_display_name': snapshot_display_name}) return context @memoized.memoized_method def get_data(self): try: share_group_snapshot = manila.share_group_snapshot_get( self.request, self.kwargs['share_group_snapshot_id']) sg = manila.share_group_get( self.request, share_group_snapshot.share_group_id) share_group_snapshot.sg_name_or_id = sg.name or sg.id except Exception: exceptions.handle( self.request, _('Unable to retrieve share group snapshot details.'), redirect=self.redirect_url) return share_group_snapshot def get_tabs(self, request, *args, **kwargs): return self.tab_group_class( request, share_group_snapshot=self.get_data(), **kwargs) class ResetShareGroupSnapshotStatusView(forms.ModalFormView): form_class = sgs_forms.ResetShareGroupSnapshotStatusForm form_id = "reset_share_group_snapshot_status" template_name = 'admin/share_group_snapshots/reset_status.html' modal_header = _("Reset Status") modal_id = "reset_share_group_snapshot_status_modal" submit_label = _("Reset status") submit_url = "horizon:admin:share_group_snapshots:reset_status" success_url = reverse_lazy("horizon:admin:share_group_snapshots:index") page_title = _("Reset Share Group Snapshot Status") def get_object(self): if not hasattr(self, "_object"): s_id = self.kwargs["share_group_snapshot_id"] try: self._object = manila.share_group_snapshot_get( self.request, s_id) except Exception: msg = _("Unable to retrieve share group snapshot '%s'.") % s_id url = reverse('horizon:admin:share_group_snapshots:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) sgs = self.get_object() context['share_group_snapshot_id'] = self.kwargs[ 'share_group_snapshot_id'] context['share_group_snapshot_name'] = sgs.name or sgs.id context['share_group_snapshot_status'] = sgs.status context['share_group_id'] = sgs.share_group_id context['submit_url'] = reverse( self.submit_url, args=(context['share_group_snapshot_id'], )) return context def get_initial(self): sgs = self.get_object() return { "share_group_snapshot_id": self.kwargs["share_group_snapshot_id"], "share_group_snapshot_name": sgs.name or sgs.id, "share_group_snapshot_status": sgs.status, "share_group_id": sgs.share_group_id, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7946513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/0000775000175000017500000000000000000000000024372 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/__init__.py0000664000175000017500000000000000000000000026471 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/forms.py0000664000175000017500000001303700000000000026076 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.conf import settings from django.forms import ValidationError from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila from manila_ui.dashboards import utils SGT_GROUP_SPECS_FORM_ATTRS = { "rows": 5, "cols": 40, "style": "height: 135px; width: 100%;", # in case 'rows' not picked up } class CreateShareGroupTypeForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Name"), required=True) group_specs = forms.CharField( required=False, label=_("Group specs"), widget=forms.widgets.Textarea(attrs=SGT_GROUP_SPECS_FORM_ATTRS)) share_types = forms.MultipleChoiceField( label=_("Share Types"), required=True, widget=forms.SelectMultiple(attrs={ "style": "height: 155px;", }), error_messages={ 'required': _("At least one share type must be specified.") }) is_public = forms.BooleanField( label=_("Public"), required=False, initial=True, help_text=("Defines whether this share group type is available for " "all or not. List of allowed tenants should be set " "separately.")) def __init__(self, request, *args, **kwargs): super(self.__class__, self).__init__(request, *args, **kwargs) manila_features = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) self.enable_public_share_group_type_creation = manila_features.get( 'enable_public_share_group_type_creation', True) if not self.enable_public_share_group_type_creation: self.fields.pop('is_public') share_type_choices = manila.share_type_list(request) self.fields['share_types'].choices = [ (choice.id, choice.name) for choice in share_type_choices] def clean(self): cleaned_data = super(CreateShareGroupTypeForm, self).clean() return cleaned_data def handle(self, request, data): try: set_dict, unset_list = utils.parse_str_meta(data['group_specs']) if unset_list: msg = _("Expected only pairs of key=value.") raise ValidationError(message=msg) is_public = ( self.enable_public_share_group_type_creation and data["is_public"]) share_group_type = manila.share_group_type_create( request, data["name"], share_types=data['share_types'], is_public=is_public) if set_dict: manila.share_group_type_set_specs( request, share_group_type.id, set_dict) msg = _("Successfully created share group type: " "%s") % share_group_type.name messages.success(request, msg) return True except ValidationError as e: # handle error without losing dialog self.api_error(e.messages[0]) return False except Exception: exceptions.handle(request, _('Unable to create share group type.')) return False class UpdateShareGroupTypeForm(forms.SelfHandlingForm): def __init__(self, *args, **kwargs): super(self.__class__, self).__init__(*args, **kwargs) # NOTE(vponomaryov): parse existing group specs # to str view for textarea html element es_str = "" for k, v in self.initial["group_specs"].items(): es_str += "%s=%s\r\n" % (k, v) self.initial["group_specs"] = es_str group_specs = forms.CharField( required=False, label=_("Group specs"), widget=forms.widgets.Textarea(attrs=SGT_GROUP_SPECS_FORM_ATTRS)) def handle(self, request, data): try: set_dict, unset_list = utils.parse_str_meta(data['group_specs']) if set_dict: manila.share_group_type_set_specs( request, self.initial["id"], set_dict) if unset_list: get = manila.share_group_type_get_specs( request, self.initial["id"]) # NOTE(vponomaryov): skip keys that are already unset to_unset = set(unset_list).intersection(set(get.keys())) if to_unset: manila.share_group_type_unset_specs( request, self.initial["id"], to_unset) msg = _( "Successfully updated group specs for share group type '%s'.") msg = msg % self.initial['name'] messages.success(request, msg) return True except ValidationError as e: # handle error without losing dialog self.api_error(e.messages[0]) return False except Exception: msg = _("Unable to update group_specs for share group type.") exceptions.handle(request, msg) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/panel.py0000664000175000017500000000171200000000000026044 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareGroupTypes(horizon.Panel): name = _("Share Group Types") slug = 'share_group_types' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareGroupTypes) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/tables.py0000664000175000017500000000725100000000000026223 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import tables from manila_ui.api import manila class CreateShareGroupType(tables.LinkAction): name = "create" verbose_name = _("Create Share Group Type") url = "horizon:admin:share_group_types:create" classes = ("ajax-modal", "btn-create") icon = "plus" class DeleteShareGroupType(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Group Type", u"Delete Share Group Types", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Group Type", u"Deleted Share Group Types", count ) def delete(self, request, obj_id): manila.share_group_type_delete(request, obj_id) class ManageShareGroupTypeAccess(tables.LinkAction): name = "manage" verbose_name = _("Manage Share Group Type Access") url = "horizon:admin:share_group_types:manage_access" classes = ("ajax-modal", "btn-create") def allowed(self, request, obj_id): sgt = manila.share_group_type_get(request, obj_id) # Enable it only for private share group types return not sgt.is_public def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} class UpdateShareGroupType(tables.LinkAction): name = "update share group type" verbose_name = _("Update Share group Type") url = "horizon:admin:share_group_types:update" classes = ("ajax-modal", "btn-create") def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} class ShareGroupTypesTable(tables.DataTable): name = tables.WrappingColumn("name", verbose_name=_("Name")) group_specs = tables.Column("group_specs", verbose_name=_("Group specs")) share_types = tables.Column("share_types", verbose_name=_("Share types")) visibility = tables.Column( "is_public", verbose_name=_("Visibility"), filters=(lambda d: 'public' if d is True else 'private', ), ) is_default = tables.Column( "is_default", verbose_name=_("Is default"), filters=(lambda d: 'Yes' if d is True else '-', ), ) def get_object_display(self, share_group_type): return share_group_type.name def get_object_id(self, share_group_type): return str(share_group_type.id) class Meta(object): name = "share_group_types" verbose_name = _("Share Group Types") table_actions = ( tables.NameFilterAction, CreateShareGroupType, DeleteShareGroupType, ) row_actions = ( UpdateShareGroupType, ManageShareGroupTypeAccess, DeleteShareGroupType, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/0000775000175000017500000000000000000000000026370 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/0000775000175000017500000000000000000000000032132 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_create.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_create.ht0000664000175000017500000000070200000000000034070 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "The share group type defines the characteristics of a share group backend." %}

Extra specs field:
{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add group-specs use:" %}

key=value

{% endblock %} ././@PaxHeader0000000000000000000000000000021500000000000011453 xustar0000000000000000119 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_manage_access.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_manage_ac0000664000175000017500000000327700000000000034120 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block form_id %}{% endblock %} {% block form_action %}{% url 'horizon:admin:share_group_types:manage_access' share_group_type.id %}{% endblock %} {% block modal_id %}manage_share_group_type_access_modal{% endblock %} {% block modal-header %}{% trans "Manage Share Group Type Access" %}{% endblock %} {% block modal-body %}
{% include "horizon/common/_form_fields.html" %}

{% trans "Description" %}:

{% blocktrans trimmed %} Placeholder for description of share group type access managing form. {% endblocktrans %}

{% include "horizon/common/_form_fields.html" %}
{{ step.get_help_text }}
{% endblock %} {% block modal-footer %} {% trans "Cancel" %} {% endblock %} ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_update.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_update.ht0000664000175000017500000000105400000000000034110 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "Here can be modified group-specs for share group type." %}
{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add group-specs use:" %}

key=value
{% trans "To unset group-specs use:" %}
key
{% trans "All pairs that are in field for left are set for this share group type." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/create.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/create.htm0000664000175000017500000000031100000000000034102 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Group Share Type" %}{% endblock %} {% block main %} {% include 'admin/share_group_types/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/index.html0000664000175000017500000000035500000000000034132 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Types" %}{% endblock %} {% block main %}
{{ share_group_types_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/manage_access.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/manage_acc0000664000175000017500000000032700000000000034115 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Manage Share Group Type Access" %}{% endblock %} {% block main %} {% include 'admin/share_group_types/_manage_access.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/update.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/templates/share_group_types/update.htm0000664000175000017500000000031100000000000034121 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Update Share Group Type" %}{% endblock %} {% block main %} {% include 'admin/share_group_types/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/urls.py0000664000175000017500000000252300000000000025733 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.urls import re_path from manila_ui.dashboards.admin.share_group_types import views from manila_ui import features if features.is_share_groups_enabled(): urlpatterns = [ re_path( r'^$', views.ShareGroupTypesView.as_view(), name='index'), re_path( r'^create$', views.CreateShareGroupTypeView.as_view(), name='create'), re_path( r'^(?P[^/]+)/update$', views.UpdateShareGroupTypeView.as_view(), name='update'), re_path( r'^(?P[^/]+)/manage_access$', views.ManageShareGroupTypeAccessView.as_view(), name='manage_access'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/views.py0000664000175000017500000001151000000000000026077 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. """ Admin views for managing share group types. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon.utils import memoized from horizon import workflows from manila_ui.api import manila from manila_ui.dashboards.admin.share_group_types import forms as sgt_forms from manila_ui.dashboards.admin.share_group_types import tables as sgt_tables import manila_ui.dashboards.admin.share_group_types.workflows as sgt_workflows from manila_ui.dashboards import utils as common_utils class ShareGroupTypesView(tables.MultiTableView): table_classes = ( sgt_tables.ShareGroupTypesTable, ) template_name = "admin/share_group_types/index.html" page_title = _("Share Group Types") @memoized.memoized_method def get_share_group_types_data(self): try: share_group_types = manila.share_group_type_list(self.request) except Exception: exceptions.handle( self.request, _('Unable to retrieve share group types.')) return [] share_types = manila.share_type_list(self.request) st_mapping = {} for st in share_types: st_mapping[st.id] = st.name for sgt in share_group_types: sgt.group_specs = common_utils.metadata_to_str( sgt.group_specs, 8, 45) sgt.share_types = ", ".join( [st_mapping[st] for st in sgt.share_types]) return share_group_types class CreateShareGroupTypeView(forms.ModalFormView): form_class = sgt_forms.CreateShareGroupTypeForm form_id = "create_share_group_type" template_name = 'admin/share_group_types/create.html' modal_header = _("Create Share Group Type") modal_id = "create_share_group_type_modal" submit_label = _("Create") submit_url = reverse_lazy("horizon:admin:share_group_types:create") success_url = reverse_lazy("horizon:admin:share_group_types:index") page_title = _("Create Share Group Type") class ManageShareGroupTypeAccessView(workflows.WorkflowView): workflow_class = sgt_workflows.ManageShareGroupTypeAccessWorkflow template_name = "admin/share_group_types/manage_access.html" success_url = 'horizon:admin:share_group_types:index' page_title = _("Manage Share Group Type Access") def get_initial(self): return {'id': self.kwargs["share_group_type_id"]} def get_context_data(self, **kwargs): context = super(ManageShareGroupTypeAccessView, self).get_context_data( **kwargs) context['id'] = self.kwargs['share_group_type_id'] return context class UpdateShareGroupTypeView(forms.ModalFormView): form_class = sgt_forms.UpdateShareGroupTypeForm form_id = "update_share_group_type" template_name = "admin/share_group_types/update.html" modal_header = _("Update Share Group Type") modal_id = "update_share_group_type_modal" submit_label = _("Update") submit_url = "horizon:admin:share_group_types:update" success_url = reverse_lazy("horizon:admin:share_group_types:index") page_title = _("Update Share Group Type") def get_object(self): if not hasattr(self, "_object"): sgt_id = self.kwargs["share_group_type_id"] try: self._object = manila.share_group_type_get( self.request, sgt_id) except Exception: msg = _("Unable to retrieve share_gruop_type.") url = reverse("horizon:admin:share_group_types:index") exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(UpdateShareGroupTypeView, self).get_context_data( **kwargs) args = ( self.get_object().id, ) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): share_group_type = self.get_object() return { "id": self.kwargs["share_group_type_id"], "name": share_group_type.name, "group_specs": share_group_type.group_specs, } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_group_types/workflows.py0000664000175000017500000001101600000000000027000 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import workflows from openstack_dashboard.api import keystone from manila_ui.api import manila class AddProjectAction(workflows.MembershipAction): def __init__(self, request, *args, **kwargs): super(AddProjectAction, self).__init__(request, *args, **kwargs) default_role_field_name = self.get_default_role_field_name() self.fields[default_role_field_name] = forms.CharField(required=False) self.fields[default_role_field_name].initial = 'member' field_name = self.get_member_field_name('member') self.fields[field_name] = forms.MultipleChoiceField(required=False) share_group_type_id = self.initial['id'] # Get list of existing projects try: projects, __ = keystone.tenant_list(request) except Exception: err_msg = _('Unable to get list of projects.') exceptions.handle(request, err_msg) # Get list of projects with access to this Share Group Type try: share_group_type = manila.share_group_type_get( request, share_group_type_id) self.share_group_type_name = share_group_type.name projects_initial = manila.share_group_type_access_list( request, share_group_type) except Exception: err_msg = _( 'Unable to get information about share group type access.') exceptions.handle(request, err_msg) self.fields[field_name].choices = [ (project.id, project.name or project.id) for project in projects] self.fields[field_name].initial = [ pr.project_id for pr in projects_initial] self.projects_initial = set(self.fields[field_name].initial) class Meta(object): name = _("Projects with access to share group type") slug = "update_members" def handle(self, request, context): context.update({ 'name': self.share_group_type_name, 'projects_add': self.projects_allow - self.projects_initial, 'projects_remove': self.projects_initial - self.projects_allow, }) return context def clean(self): cleaned_data = super(AddProjectAction, self).clean() self.projects_allow = set( cleaned_data[self.get_member_field_name('member')]) return cleaned_data class AddProjectStep(workflows.UpdateMembersStep): action_class = AddProjectAction available_list_title = _("Available projects") help_text = _("Allow project access to share group type.") members_list_title = _("Selected projects") no_available_text = _("No projects found.") no_members_text = _("No projects selected.") depends_on = ("id", ) show_roles = False class ManageShareGroupTypeAccessWorkflow(workflows.Workflow): slug = "manage_share_group_type_access" name = _("Manage Share Group Type Access") finalize_button_name = _("Manage Share Group Type Access") success_message = _('Updated access for share group type "%s".') failure_message = _('Unable to update access for share group type "%s".') success_url = 'horizon:admin:share_group_types:index' default_steps = (AddProjectStep, ) def format_status_message(self, message): return message % self.context['name'] def handle(self, request, context): try: for project in self.context['projects_remove']: manila.share_group_type_access_remove( request, self.context['id'], project) for project in self.context['projects_add']: manila.share_group_type_access_add( request, self.context['id'], project) return True except Exception: exceptions.handle(request, _('Unable to update share group type.')) return False ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/0000775000175000017500000000000000000000000023331 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/__init__.py0000664000175000017500000000000000000000000025430 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/forms.py0000664000175000017500000000363400000000000025037 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class ResetShareGroupStatusForm(forms.SelfHandlingForm): status = forms.ChoiceField( label=_("Status"), required=True, choices=( ('available', 'available'), ('error', 'error'), ) ) def handle(self, request, data): sg_id = self.initial['share_group_id'] try: manila.share_group_reset_state(request, sg_id, data["status"]) message = _( "Reseting share group ('%(id)s') status from '%(from)s' " "to '%(to)s'.") % { "id": (self.initial['share_group_name'] or self.initial['share_group_id']), "from": self.initial['share_group_status'], "to": data["status"]} messages.success(request, message) return True except Exception: redirect = reverse("horizon:admin:share_groups:index") exceptions.handle( request, _("Unable to reset status of share group '%s'.") % sg_id, redirect=redirect) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/panel.py0000664000175000017500000000167000000000000025006 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareGroups(horizon.Panel): name = _("Share Groups") slug = 'share_groups' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareGroups) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/tables.py0000664000175000017500000000743300000000000025164 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import tables from manila_ui.api import manila class DeleteShareGroup(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Group", u"Delete Share Groups", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Group", u"Deleted Share Groups", count ) def delete(self, request, obj_id): manila.share_group_delete(request, obj_id) class ResetShareGroupStatus(tables.LinkAction): name = "reset_share_group_status" verbose_name = _("Reset status") url = "horizon:admin:share_groups:reset_status" classes = ("ajax-modal", "btn-create") def allowed(self, request, share_group=None): return True class ShareGroupsTable(tables.DataTable): def get_share_network_link(share_group): if getattr(share_group, 'share_network_id', None): return reverse("horizon:admin:share_networks:share_network_detail", args=(share_group.share_network_id,)) else: return None def get_share_server_link(share_group): if getattr(share_group, 'share_server_id', None): return reverse("horizon:admin:share_servers:share_server_detail", args=(share_group.share_server_id,)) else: return None STATUS_CHOICES = ( ("available", True), ("creating", None), ("deleting", None), ("error", False), ("error_deleting", False), ) STATUS_DISPLAY_CHOICES = ( ("available", u"Available"), ("creating", u"Creating"), ("deleting", u"Deleting"), ("error", u"Error"), ("error_deleting", u"Error deleting"), ) name = tables.Column( "name", verbose_name=_("Name"), link="horizon:admin:share_groups:detail") host = tables.Column("host", verbose_name=_("Host")) status = tables.Column( "status", verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES, ) availability_zone = tables.Column( "availability_zone", verbose_name=_("Availability Zone")) share_network_id = tables.Column( "share_network_id", verbose_name=_("Share Network"), link=get_share_network_link) share_server_id = tables.Column( "share_server_id", verbose_name=_("Share Server"), link=get_share_server_link) def get_object_display(self, share_group): return str(share_group.id) def get_object_id(self, share_group): return str(share_group.id) class Meta(object): name = "share_groups" verbose_name = _("Share Groups") status_columns = ("status", ) table_actions = ( tables.NameFilterAction, DeleteShareGroup, ) row_actions = ( ResetShareGroupStatus, DeleteShareGroup, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/tabs.py0000664000175000017500000000213700000000000024637 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareGroupOverviewTab(tabs.Tab): name = _("Share Group Overview") slug = "share_group_overview_tab" template_name = "admin/share_groups/_detail.html" def get_context_data(self, request): return {"share_group": self.tab_group.kwargs["share_group"]} class ShareGroupDetailTabs(tabs.TabGroup): slug = "share_group_details" tabs = ( ShareGroupOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/0000775000175000017500000000000000000000000025327 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/share_groups/0000775000175000017500000000000000000000000030030 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/share_groups/_detail.html0000664000175000017500000000643500000000000032327 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Group Overview" %}


{% trans "ID" %}
{{ share_group.id }}
{% trans "Name" %}
{{ share_group.name }}
{% trans "Description" %}
{{ share_group.description }}
{% trans "Status" %}
{{ share_group.status|capfirst }}
{% trans "Created" %}
{{ share_group.created_at|parse_date }}
{% trans "Host" %}
{{ share_group.host}}
{% if share_group.source_share_group_snapshot_id %}
{% trans "Source share group snapshot" %}
{{ share_group.source_share_group_snapshot_id}}
{% endif %}
{% trans "Capabilities" %}
{% if share_group.consistent_snapshot_support %} Consistent snapshots are supported at storage {{ share_group.consistent_snapshot_support }} level {% else %} None {% endif %}
{% if share_group.availability_zone %}
{% trans "Availability Zone" %}
{{ share_group.availability_zone }}
{% endif %} {% if share_group.share_network_id %}
{% trans "Share network" %}
{% url 'horizon:admin:share_networks:share_network_detail' share_group.share_network_id as sn_url%}
{{ share_group.share_network_id }}
{% endif %} {% if share_group.share_server_id %}
{% trans "Share server" %}
{% url 'horizon:admin:share_servers:share_server_detail' share_group.share_server_id as share_server_url%}
{{ share_group.share_server_id }}
{% endif %} {% if share_group.share_group_type %}
{% trans "Share Group Type" %}
{% url 'horizon:admin:share_group_types:index' as sgts_url %}
{% trans "Share Group Type Name:" %} {{ share_group.share_group_type.name }}
{% trans "Share Group Type ID:" %} {{ share_group.share_group_type.id }}
{% trans "Share Group Type Specs:" %} {{ share_group.share_group_type.group_specs }}

{% endif %} {% if share_group.share_types %}
{% trans "Share Types" %}
{% for st in share_group.share_types %}
{% trans "Share Type Name:" %} {{ st.name }}
{% trans " Share Type Visibility:" %} {% if st.is_public %}Public{% else %}Private{% endif %}
{% trans "Network handling enabled:" %} {{ st.dhss }}

{% endfor %} {% endif %} {% if share_group.members %}
{% trans "Shares" %}
{% for m in share_group.members %} {% url 'horizon:admin:shares:detail' m.id as share_url%}
{% endfor %} {% endif %}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/share_groups/_reset_status.html0000664000175000017500000000026600000000000033606 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

"Reset status of '{{ share_group_name }}' share group."

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/share_groups/detail.html0000664000175000017500000000034100000000000032156 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/share_groups/index.html0000664000175000017500000000034300000000000032025 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Groups" %}{% endblock %} {% block main %}
{{ share_groups_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/templates/share_groups/reset_status.html0000664000175000017500000000031300000000000033440 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Reset Share Group Status" %}{% endblock %} {% block main %} {% include 'admin/share_groups/_reset_status.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/urls.py0000664000175000017500000000226200000000000024672 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # 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. from django.urls import re_path from manila_ui.dashboards.admin.share_groups import views from manila_ui import features if features.is_share_groups_enabled(): urlpatterns = [ re_path( r'^$', views.ShareGroupsView.as_view(), name='index'), re_path( r'^(?P[^/]+)/$', views.ShareGroupDetailView.as_view(), name='detail'), re_path( r'^(?P[^/]+)/reset_status$', views.ResetShareGroupStatusView.as_view(), name='reset_status'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_groups/views.py0000664000175000017500000001216600000000000025046 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. """ Admin views for managing share groups. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.share_groups import forms as sg_forms from manila_ui.dashboards.admin.share_groups import tables as sg_tables from manila_ui.dashboards.admin.share_groups import tabs as sg_tabs class ShareGroupsView(tables.MultiTableView): table_classes = ( sg_tables.ShareGroupsTable, ) template_name = "admin/share_groups/index.html" page_title = _("Share Groups") @memoized.memoized_method def get_share_groups_data(self): try: share_groups = manila.share_group_list( self.request, detailed=True) except Exception: share_groups = [] exceptions.handle( self.request, _("Unable to retrieve share groups.")) return share_groups class ShareGroupDetailView(tabs.TabView): tab_group_class = sg_tabs.ShareGroupDetailTabs template_name = 'admin/share_groups/detail.html' def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) share_group = self.get_data() context["share_group"] = share_group context["page_title"] = ( _("Share Group Details: %s") % share_group.id) return context @memoized.memoized_method def get_data(self): try: share_group_id = self.kwargs['share_group_id'] share_group = manila.share_group_get(self.request, share_group_id) members = manila.share_list( self.request, search_opts={"share_group_id": share_group_id}) share_group.members = members share_group.share_group_type = manila.share_group_type_get( self.request, share_group.share_group_type_id) share_types = manila.share_type_list(self.request) share_group.share_types = [ {"id": st.id, "name": st.name, "is_public": getattr(st, 'share_type_access:is_public'), "dhss": st.extra_specs.get('driver_handles_share_servers')} for st in share_types if st.id in share_group.share_types ] return share_group except Exception: redirect = reverse('horizon:admin:share_groups:index') exceptions.handle( self.request, _('Unable to retrieve share group details.'), redirect=redirect) def get_tabs(self, request, *args, **kwargs): share_group = self.get_data() return self.tab_group_class(request, share_group=share_group, **kwargs) class ResetShareGroupStatusView(forms.ModalFormView): form_class = sg_forms.ResetShareGroupStatusForm form_id = "reset_share_group_status" template_name = 'admin/share_groups/reset_status.html' modal_header = _("Reset Status") modal_id = "reset_share_group_status_modal" submit_label = _("Reset status") submit_url = "horizon:admin:share_groups:reset_status" success_url = reverse_lazy("horizon:admin:share_groups:index") page_title = _("Reset Share Group Status") def get_object(self): if not hasattr(self, "_object"): sg_id = self.kwargs["share_group_id"] try: self._object = manila.share_group_get(self.request, sg_id) except Exception: msg = _("Unable to retrieve share group '%s'.") % sg_id url = reverse('horizon:admin:share_groups:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) sg = self.get_object() context['share_group_id'] = self.kwargs['share_group_id'] context['share_group_name'] = sg.name or sg.id context['share_group_status'] = sg.status context['submit_url'] = reverse( self.submit_url, args=(context['share_group_id'], )) return context def get_initial(self): sg = self.get_object() return { "share_group_id": self.kwargs["share_group_id"], "share_group_name": sg.name or sg.id, "share_group_status": sg.status, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/0000775000175000017500000000000000000000000024001 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/__init__.py0000664000175000017500000000000000000000000026100 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/panel.py0000664000175000017500000000165500000000000025461 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareInstances(horizon.Panel): name = _("Share Instances") slug = 'share_instances' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareInstances) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/tables.py0000664000175000017500000000623300000000000025631 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import tables class ShareInstancesTable(tables.DataTable): STATUS_CHOICES = ( ("available", True), ("creating", None), ("deleting", None), ("error", False), ("error_deleting", False), ) STATUS_DISPLAY_CHOICES = ( ("available", u"Available"), ("creating", u"Creating"), ("deleting", u"Deleting"), ("error", u"Error"), ("error_deleting", u"Error deleting"), ) uuid = tables.Column( "id", verbose_name=_("ID"), link="horizon:admin:share_instances:share_instance_detail") host = tables.Column("host", verbose_name=_("Host")) status = tables.Column( "status", verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) availability_zone = tables.Column( "availability_zone", verbose_name=_("Availability Zone")) class Meta(object): name = "share_instances" verbose_name = _("Share Instances") status_columns = ("status", ) table_actions = ( tables.NameFilterAction,) multi_select = False def get_share_network_link(share_instance): if getattr(share_instance, 'share_network_id', None): return reverse("horizon:admin:share_networks:share_network_detail", args=(share_instance.share_network_id,)) else: return None def get_share_server_link(share_instance): if getattr(share_instance, 'share_server_id', None): return reverse("horizon:admin:share_servers:share_server_detail", args=(share_instance.share_server_id,)) else: return None def get_share_link(share_instance): if getattr(share_instance, 'share_id', None): return reverse("horizon:admin:shares:detail", args=(share_instance.share_id,)) else: return None share_net_id = tables.Column( "share_network_id", verbose_name=_("Share Network"), link=get_share_network_link) share_server_id = tables.Column( "share_server_id", verbose_name=_("Share Server Id"), link=get_share_server_link) share_id = tables.Column( "share_id", verbose_name=_("Share ID"), link=get_share_link) def get_object_display(self, share_instance): return str(share_instance.id) def get_object_id(self, share_instance): return str(share_instance.id) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/tabs.py0000664000175000017500000000214300000000000025304 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareInstanceOverviewTab(tabs.Tab): name = _("Share Instance Overview") slug = "share_instance_overview_tab" template_name = "admin/share_instances/_detail.html" def get_context_data(self, request): return {"share_instance": self.tab_group.kwargs["share_instance"]} class ShareInstanceDetailTabs(tabs.TabGroup): slug = "share_instance_details" tabs = ( ShareInstanceOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/templates/0000775000175000017500000000000000000000000025777 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/templates/share_instances/0000775000175000017500000000000000000000000031150 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/templates/share_instances/_detail.html0000664000175000017500000000374300000000000033446 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Instance Overview" %}


{% trans "ID" %}
{{ share_instance.id }}
{% trans "Status" %}
{{ share_instance.status|capfirst }}
{% trans "Export locations" %}
{% if share_instance.export_locations %} {% for el in share_instance.export_locations %}

Path:
Preferred: {{ el.preferred }}
{% if el.is_admin_only == True or el.is_admin_only == False %}
Is admin only: {{ el.is_admin_only }}
{% endif %}

{% endfor %} {% endif %}
{% trans "Host" %}
{{ share_instance.host}}
{% trans "Availability Zone" %}
{{ share_instance.availability_zone}}
{% trans "Share ID" %}
{% url 'horizon:admin:shares:detail' share_instance.share_id as share_url %}
{{ share_instance.share_id }}
{% if share_instance.share_network_id %}
{% trans "Share network" %}
{% url 'horizon:admin:share_networks:share_network_detail' share_instance.share_network_id as sn_url%}
{{ share_instance.share_network_id }}
{% endif %} {% if share_instance.share_server_id %}
{% trans "Share server" %}
{% url 'horizon:admin:share_servers:share_server_detail' share_instance.share_server_id as share_server_url%}
{{ share_instance.share_server_id }}
{% endif %}
{% trans "Created" %}
{{ share_instance.created_at|parse_date }}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/templates/share_instances/detail.html0000664000175000017500000000034400000000000033301 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Instance Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/templates/share_instances/index.html0000664000175000017500000000035100000000000033144 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Instances" %}{% endblock %} {% block main %}
{{ share_instances_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/urls.py0000664000175000017500000000160300000000000025340 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.share_instances import views urlpatterns = [ re_path( r'^$', views.ShareInstancesView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.ShareInstanceDetailView.as_view(), name='share_instance_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_instances/views.py0000664000175000017500000000626000000000000025514 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Admin views for managing share instances. """ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.share_instances import tables as si_tables from manila_ui.dashboards.admin.share_instances import tabs as si_tabs from manila_ui.dashboards import utils as ui_utils class ShareInstancesView(tables.MultiTableView): table_classes = ( si_tables.ShareInstancesTable, ) template_name = "admin/share_instances/index.html" page_title = _("Share Instances") @memoized.memoized_method def get_share_instances_data(self): try: share_instances = manila.share_instance_list(self.request) except Exception: share_instances = [] exceptions.handle( self.request, _("Unable to retrieve share instances.")) return share_instances class ShareInstanceDetailView(tabs.TabView): tab_group_class = si_tabs.ShareInstanceDetailTabs template_name = 'admin/share_instances/detail.html' def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) share_instance = self.get_data() context["share_instance"] = share_instance context["page_title"] = ( _("Share Instance Details: %s") % share_instance.id) return context @memoized.memoized_method def get_data(self): try: share_instance_id = self.kwargs['share_instance_id'] share_instance = manila.share_instance_get( self.request, share_instance_id) share_instance.export_locations = ( manila.share_instance_export_location_list( self.request, share_instance_id)) export_locations = [ exp['path'] for exp in share_instance.export_locations ] share_instance.el_size = ui_utils.calculate_longest_str_size( export_locations) return share_instance except Exception: redirect = reverse('horizon:admin:share_instances:index') exceptions.handle( self.request, _('Unable to retrieve share instance details.'), redirect=redirect) def get_tabs(self, request, *args, **kwargs): share_instance = self.get_data() return self.tab_group_class( request, share_instance=share_instance, **kwargs) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/0000775000175000017500000000000000000000000023666 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/__init__.py0000664000175000017500000000000000000000000025765 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/panel.py0000664000175000017500000000165100000000000025342 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareNetworks(horizon.Panel): name = _("Share Networks") slug = 'share_networks' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareNetworks) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/tables.py0000664000175000017500000000265700000000000025524 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tables import manila_ui.dashboards.project.share_networks.tables as sn_tables class ShareNetworksTable(tables.DataTable): name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:admin:share_networks:share_network_detail") project = tables.Column("project_name", verbose_name=_("Project")) def get_object_display(self, share_network): return share_network.name or str(share_network.id) def get_object_id(self, share_network): return str(share_network.id) class Meta(object): name = "share_networks" verbose_name = _("Share Networks") table_actions = ( tables.NameFilterAction, sn_tables.Delete, ) row_class = sn_tables.UpdateRow row_actions = ( sn_tables.Delete, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/tabs.py0000664000175000017500000000213200000000000025167 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareNetworkOverviewTab(tabs.Tab): name = _("Share Network Overview") slug = "share_network_overview_tab" template_name = "admin/share_networks/_detail.html" def get_context_data(self, request): return {"share_network": self.tab_group.kwargs["share_network"]} class ShareNetworkDetailTabs(tabs.TabGroup): slug = "share_network_details" tabs = ( ShareNetworkOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/templates/0000775000175000017500000000000000000000000025664 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7986515 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/templates/share_networks/0000775000175000017500000000000000000000000030722 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/templates/share_networks/_detail.html0000664000175000017500000000570000000000000033213 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}
{% trans "Name" %}
{{ share_network.name }}
{% if share_network.description %}
{% trans "Description" %}
{{ share_network.description }}
{% endif %} {% if share_network.created_at %}
{% trans "Created At" %}
{{ share_network.created_at }}
{% endif %} {% if share_network.updated_at %}
{% trans "Updated At" %}
{{ share_network.updated_at }}
{% endif %}
{% trans "Share Network ID" %}
{{ share_network.id }}
{% trans "Project ID" %}
{{ share_network.project_id }}

{% trans "Subnets" %}


{% for subnet in share_network.share_network_subnets %}
{% trans "Id" %}
{{subnet.id}}
{% if subnet.neutron_net != "Unknown" %} {% url 'horizon:admin:networks:detail' subnet.neutron_net_id as network_detail_url %}
{% trans "Neutron Network" %}
{{subnet.neutron_net}}
{% endif %} {% if subnet.neutron_subnet != "Unknown" %} {% url 'horizon:admin:networks:subnets:detail' subnet.neutron_subnet_id as subnet_detail_url %}
{% trans "Neutron Subnet" %}
{{subnet.neutron_subnet}}
{% endif %}
{% trans "Availability Zone" %}
{{subnet.availability_zone}}
{% endfor %}
{% if share_network.share_servers %}

{% trans "Share Servers" %}


{% for server in share_network.share_servers %}
    {% url 'horizon:admin:share_servers:share_server_detail' server.id as server_url %}
  • {{server.id }}
{% endfor %}
{% endif %} {% if share_network.sec_services %}

{% trans "Security Services" %}


{% for sec_service in share_network.sec_services %} {% url 'horizon:admin:security_services:security_service_detail' sec_service.id as sec_service_url%}
{% trans "Id" %}
{{ sec_service.id }}
{% trans "Name" %}
{{ sec_service.name }}
{% trans "Type" %}
{{ sec_service.type }}

{% endfor %}
{% endif %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/templates/share_networks/detail.html0000664000175000017500000000034300000000000033052 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Network Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/templates/share_networks/index.html0000664000175000017500000000034700000000000032723 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Networks" %}{% endblock %} {% block main %}
{{ share_networks_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/urls.py0000664000175000017500000000157600000000000025236 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.share_networks import views urlpatterns = [ re_path( r'^$', views.ShareNetworksView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.ShareNetworkDetailView.as_view(), name='share_network_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_networks/views.py0000664000175000017500000000400300000000000025372 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Admin views for managing share networks. """ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.share_networks import tables as sn_tables from manila_ui.dashboards.admin.share_networks import tabs as sn_tabs from manila_ui.dashboards.admin import utils from manila_ui.dashboards.project.share_networks import views as p_views class ShareNetworksView(tables.MultiTableView): table_classes = ( sn_tables.ShareNetworksTable, ) template_name = "admin/share_networks/index.html" page_title = _("Share Networks") @memoized.memoized_method def get_share_networks_data(self): try: share_networks = manila.share_network_list( self.request, detailed=True, search_opts={"all_tenants": True}) except Exception: share_networks = [] exceptions.handle( self.request, _("Unable to retrieve share networks")) utils.set_project_name_to_objects(self.request, share_networks) return share_networks class ShareNetworkDetailView(p_views.Detail): tab_group_class = sn_tabs.ShareNetworkDetailTabs template_name = "admin/share_networks/detail.html" redirect_url = reverse_lazy("horizon:admin:share_networks:index") ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8026514 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/0000775000175000017500000000000000000000000023503 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/__init__.py0000664000175000017500000000000000000000000025602 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/panel.py0000664000175000017500000000164500000000000025162 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareServers(horizon.Panel): name = _("Share Servers") slug = 'share_servers' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareServers) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/tables.py0000664000175000017500000000756400000000000025343 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.template.defaultfilters import title from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import tables from manila_ui.api import manila class DeleteShareServer(tables.DeleteAction): policy_rules = (("share", "share_server:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Server", u"Delete Share Server", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Server", u"Deleted Share Server", count ) def delete(self, request, obj_id): manila.share_server_delete(request, obj_id) def allowed(self, request, share_serv): if share_serv: share_search_opts = {'share_server_id': share_serv.id} shares_list = manila.share_list( request, search_opts=share_search_opts) if shares_list: return False return share_serv.status not in ("deleting", "creating") return True class UpdateShareServerRow(tables.Row): ajax = True def get_data(self, request, share_serv_id): share_serv = manila.share_server_get(request, share_serv_id) return share_serv class ShareServersTable(tables.DataTable): STATUS_CHOICES = ( ("active", True), ("deleting", None), ("creating", None), ("error", False), ) STATUS_DISPLAY_CHOICES = ( ("in-use", pgettext_lazy("Current status of share server", u"In-use")), ("active", pgettext_lazy("Current status of share server", u"Active")), ("creating", pgettext_lazy("Current status of share server", u"Creating")), ("error", pgettext_lazy("Current status of share server", u"Error")), ) uid = tables.Column( "id", verbose_name=_("Id"), link="horizon:admin:share_servers:share_server_detail") host = tables.Column("host", verbose_name=_("Host")) project = tables.Column("project_name", verbose_name=_("Project")) def get_share_server_link(share_serv): if hasattr(share_serv, 'share_network_id'): return reverse("horizon:admin:share_networks:share_network_detail", args=(share_serv.share_network_id,)) else: return None share_net_name = tables.Column( "share_network_name", verbose_name=_("Share Network"), link=get_share_server_link) status = tables.Column( "status", verbose_name=_("Status"), status=True, filters=(title,), status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) def get_object_display(self, share_server): return str(share_server.id) def get_object_id(self, share_server): return str(share_server.id) class Meta(object): name = "share_servers" status_columns = ["status"] verbose_name = _("Share Server") table_actions = ( tables.NameFilterAction, DeleteShareServer, ) row_class = UpdateShareServerRow row_actions = ( DeleteShareServer, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/tabs.py0000664000175000017500000000212700000000000025010 0ustar00zuulzuul00000000000000# Copyright 2014 OpenStack Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareServerOverviewTab(tabs.Tab): name = _("Share Server Overview") slug = "share_server_overview_tab" template_name = "admin/share_servers/_detail.html" def get_context_data(self, request): return {"share_server": self.tab_group.kwargs["share_server"]} class ShareServerDetailTabs(tabs.TabGroup): slug = "share_server_details" tabs = ( ShareServerOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/templates/0000775000175000017500000000000000000000000025501 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8026514 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/templates/share_servers/0000775000175000017500000000000000000000000030354 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/templates/share_servers/_detail.html0000664000175000017500000000242000000000000032641 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Server Overview" %}


{% trans "ID" %}
{{ share_server.id }}
{% trans "Status" %}
{{ share_server.status|capfirst }}
{% trans "Host" %}
{{ share_server.host}}
{% trans "Share Network" %}
{% if share_server.share_network_id %} {% url 'horizon:admin:share_networks:share_network_detail' share_server.share_network_id as share_net_url %}
{{ share_server.share_network_name }}
{% else %}
{{ share_server.share_network_name }}
{% endif %} {% if share_server.shares_list %}
{% trans "Shares on this server" %}
{% for share in share_server.shares_list %} {% url 'horizon:admin:shares:detail' share.id as share_url %}
{{ share.name_or_id }}
{% endfor %} {% endif %}

{% trans "Specs" %}


{% for key, value in share_server.backend_details.items %}
{{ key }}
{{ value }}
{% endfor %}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/templates/share_servers/detail.html0000664000175000017500000000034200000000000032503 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Server Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/templates/share_servers/index.html0000664000175000017500000000034500000000000032353 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Servers" %}{% endblock %} {% block main %}
{{ share_servers_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/urls.py0000664000175000017500000000157100000000000025046 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.share_servers import views urlpatterns = [ re_path( r'^$', views.ShareServersView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.ShareServerDetailView.as_view(), name='share_server_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_servers/views.py0000664000175000017500000000670700000000000025224 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Admin views for managing share servers. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.share_servers import tables as ss_tables from manila_ui.dashboards.admin.share_servers import tabs as ss_tabs from manila_ui.dashboards.admin import utils class ShareServersView(tables.MultiTableView): table_classes = ( ss_tables.ShareServersTable, ) template_name = "admin/share_servers/index.html" page_title = _("Share Servers") @memoized.memoized_method def get_share_servers_data(self): try: share_servers = manila.share_server_list(self.request) except Exception: share_servers = [] exceptions.handle( self.request, _("Unable to retrieve share servers")) utils.set_project_name_to_objects(self.request, share_servers) return share_servers class ShareServerDetailView(tabs.TabView): tab_group_class = ss_tabs.ShareServerDetailTabs template_name = "admin/share_servers/detail.html" redirect_url = reverse_lazy('horizon:admin:share_servers:index') def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) share_server = self.get_data() share_server_display_name = share_server.id context["share_server"] = share_server context["share_server_display_name"] = share_server_display_name context["page_title"] = _("Share Server Details: %(server_name)s") % { 'server_name': share_server_display_name} return context @memoized.memoized_method def get_data(self): try: share_serv_id = self.kwargs['share_server_id'] share_serv = manila.share_server_get(self.request, share_serv_id) share_search_opts = {'share_server_id': share_serv.id} shares_list = manila.share_list( self.request, search_opts=share_search_opts) for share in shares_list: share.name_or_id = share.name or share.id share_serv.shares_list = shares_list if not hasattr(share_serv, 'share_network_id'): share_serv.share_network_id = None except Exception: redirect = reverse('horizon:admin:share_servers:index') exceptions.handle( self.request, _('Unable to retrieve share server details.'), redirect=redirect) return share_serv def get_tabs(self, request, *args, **kwargs): share_server = self.get_data() return self.tab_group_class( request, share_server=share_server, **kwargs) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8026514 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/0000775000175000017500000000000000000000000024034 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/__init__.py0000664000175000017500000000000000000000000026133 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/panel.py0000664000175000017500000000165500000000000025514 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareSnapshots(horizon.Panel): name = _("Share Snapshots") slug = 'share_snapshots' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareSnapshots) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/tables.py0000664000175000017500000001001500000000000025655 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.template.defaultfilters import title from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import exceptions from horizon import tables from manila_ui.api import manila import manila_ui.dashboards.project.share_snapshots.tables as ss_tables from manila_ui.dashboards.project.shares import tables as shares_tables def get_size(share): return _("%sGiB") % share.size class ShareSnapshotShareNameColumn(tables.Column): def get_link_url(self, snapshot): return reverse(self.link, args=(snapshot.share_id,)) class DeleteShareSnapshot(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Snapshot", u"Delete Snapshots", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Snapshot", u"Deleted Snapshots", count ) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "project_id", None) return {"project_id": project_id} def delete(self, request, obj_id): obj = self.table.get_object_by_id(obj_id) name = self.table.get_object_display(obj) try: manila.share_snapshot_delete(request, obj_id) except Exception: msg = _('Unable to delete snapshot "%s". One or more shares ' 'depend on it.') exceptions.handle(self.request, msg % name) raise def allowed(self, request, snapshot=None): if snapshot: return snapshot.status.upper() in shares_tables.DELETABLE_STATES return True class ShareSnapshotsTable(tables.DataTable): STATUS_CHOICES = ( ("in-use", True), ("available", True), ("creating", None), ("error", False), ) STATUS_DISPLAY_CHOICES = ( ("in-use", pgettext_lazy("Current status of snapshot", u"In-use")), ("available", pgettext_lazy("Current status of snapshot", u"Available")), ("creating", pgettext_lazy("Current status of snapshot", u"Creating")), ("error", pgettext_lazy("Current status of snapshot", u"Error")), ) name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:admin:share_snapshots:share_snapshot_detail") description = tables.Column( "description", verbose_name=_("Description"), truncate=40) size = tables.Column( get_size, verbose_name=_("Size"), attrs={'data-type': 'size'}) status = tables.Column( "status", filters=(title,), verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) source = ShareSnapshotShareNameColumn( "share", verbose_name=_("Source"), link="horizon:admin:shares:detail") def get_object_display(self, obj): return obj.name class Meta(object): name = "share_snapshots" verbose_name = _("Share Snapshots") status_columns = ["status"] row_class = ss_tables.UpdateShareSnapshotRow table_actions = ( tables.NameFilterAction, DeleteShareSnapshot, ) row_actions = ( DeleteShareSnapshot, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/tabs.py0000664000175000017500000000212200000000000025334 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareSnapshotOverviewTab(tabs.Tab): name = _("Share Snapshot Overview") slug = "share_snapshot_overview_tab" template_name = "admin/share_snapshots/_detail.html" def get_context_data(self, request): return {"snapshot": self.tab_group.kwargs["snapshot"]} class SnapshotDetailTabs(tabs.TabGroup): slug = "share_snapshot_details" tabs = ( ShareSnapshotOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/templates/0000775000175000017500000000000000000000000026032 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8026514 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/0000775000175000017500000000000000000000000031236 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/_detail.html0000664000175000017500000000414700000000000033533 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Snapshot Overview" %}


{% trans "Name" %}
{{ snapshot.name }}
{% trans "ID" %}
{{ snapshot.id }}
{% url 'horizon:admin:shares:detail' snapshot.share_id as share_url %}
{% trans "Source" %}
{{ snapshot.share_name_or_id }}
{% if snapshot.description %}
{% trans "Description" %}
{{ snapshot.description }}
{% endif %}
{% trans "Status" %}
{{ snapshot.status|capfirst }}
{% if snapshot.export_locations %}
{% trans "Export locations" %}
{% for el in snapshot.export_locations %}

{% trans "Path:" %}
{% if el.is_admin_only != None %}
{% trans "Is admin only:" %} {{ el.is_admin_only }}
{% endif %} {% if el.share_snapshot_instance_id %}
{% trans "Snapshot Replica ID:" %} {{ el.share_snapshot_instance_id }}
{% endif %}

{% endfor %} {% endif %}
{% if snapshot.rules != None %}

{% trans "Access Rules" %}


{% for rule in snapshot.rules %}
{{ rule.access_type }}

{% trans "Access to:" %} {{ rule.access_to }}
{% trans "Status:" %} {{ rule.state }}

{% endfor %}
{% endif %}

{% trans "Specs" %}


{% trans "Size" %}
{{ snapshot.size }} {% trans "GiB" %}
{% trans "Created" %}
{{ snapshot.created_at|parse_date }}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/detail.html0000664000175000017500000000033300000000000033365 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/index.html0000664000175000017500000000034000000000000033230 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Shares" %}{% endblock %} {% block main %}
{{ share_snapshots_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/urls.py0000664000175000017500000000157500000000000025403 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.share_snapshots import views urlpatterns = [ re_path( r'^$', views.ShareSnapshotsView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.ShareSnapshotDetailView.as_view(), name='share_snapshot_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_snapshots/views.py0000664000175000017500000000453400000000000025551 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Admin views for managing share snapshots. """ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.share_snapshots import tables as ss_tables from manila_ui.dashboards.admin.share_snapshots import tabs as ss_tabs from manila_ui.dashboards.admin import utils import manila_ui.dashboards.project.share_snapshots.views as snapshot_views class ShareSnapshotsView(tables.MultiTableView): table_classes = ( ss_tables.ShareSnapshotsTable, ) template_name = "admin/share_snapshots/index.html" page_title = _("Share Snapshots") @memoized.memoized_method def get_share_snapshots_data(self): snapshots = [] try: snapshots = manila.share_snapshot_list( self.request, search_opts={'all_tenants': True}) shares = manila.share_list(self.request) share_names = dict([(share.id, share.name or share.id) for share in shares]) for snapshot in snapshots: snapshot.share = share_names.get(snapshot.share_id) except Exception: msg = _("Unable to retrieve share snapshot list.") exceptions.handle(self.request, msg) # Gather our projects to correlate against IDs utils.set_project_name_to_objects(self.request, snapshots) return snapshots class ShareSnapshotDetailView(snapshot_views.ShareSnapshotDetailView): tab_group_class = ss_tabs.SnapshotDetailTabs template_name = "admin/share_snapshots/detail.html" redirect_url = reverse_lazy("horizon:admin:share_snapshots:index") ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8026514 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/0000775000175000017500000000000000000000000023156 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/__init__.py0000664000175000017500000000000000000000000025255 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/forms.py0000664000175000017500000001514300000000000024662 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. from django.conf import settings from django.forms import ValidationError from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila from manila_ui.dashboards import utils ST_EXTRA_SPECS_FORM_ATTRS = { "rows": 5, "cols": 40, "style": "height: 135px; width: 100%;", # in case 'rows' not picked up } class CreateShareType(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Name"), required=True) description = forms.CharField(widget=forms.Textarea, max_length="255", label=_("Description"), required=False) spec_driver_handles_share_servers = forms.ChoiceField( label=_("Driver handles share servers"), required=True, choices=(('False', 'False'), ('True', 'True'))) extra_specs = forms.CharField( required=False, label=_("Extra specs"), widget=forms.widgets.Textarea(attrs=ST_EXTRA_SPECS_FORM_ATTRS)) is_public = forms.BooleanField( label=_("Public"), required=False, initial=True, help_text=("Defines whether this share type is available for all " "or not. List of allowed tenants should be set " "separately.")) def __init__(self, *args, **kwargs): super(CreateShareType, self).__init__(*args, **kwargs) manila_features = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) self.enable_public_share_type_creation = manila_features.get( 'enable_public_share_type_creation', True) if not self.enable_public_share_type_creation: self.fields.pop('is_public') def handle(self, request, data): try: spec_dhss = data['spec_driver_handles_share_servers'].lower() allowed_dhss_values = ('true', 'false') if spec_dhss not in allowed_dhss_values: msg = _("Improper value set to required extra spec " "'spec_driver_handles_share_servers'. " "Allowed values are %s. " "Case insensitive.") % allowed_dhss_values raise ValidationError(message=msg) set_dict, unset_list = utils.parse_str_meta(data['extra_specs']) if unset_list: msg = _("Expected only pairs of key=value.") raise ValidationError(message=msg) is_public = (self.enable_public_share_type_creation and data["is_public"]) share_type = manila.share_type_create( request, data["name"], spec_dhss, description=data["description"], is_public=is_public) if set_dict: manila.share_type_set_extra_specs( request, share_type.id, set_dict) msg = _("Successfully created share type: %s") % share_type.name messages.success(request, msg) return True except ValidationError as e: # handle error without losing dialog self.api_error(e.messages[0]) return False except Exception: exceptions.handle(request, _('Unable to create share type.')) return False class UpdateShareType(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Name"), required=True) description = forms.CharField(max_length="255", label=_("Description"), required=False) is_public = forms.BooleanField( label=_("Public"), required=False, help_text=("New visibility of the share type. If set to True, share " "type will be available to all projects in the cloud.")) extra_specs = forms.CharField( required=False, label=_("Extra specs"), widget=forms.widgets.Textarea(attrs=ST_EXTRA_SPECS_FORM_ATTRS)) def __init__(self, *args, **kwargs): super(UpdateShareType, self).__init__(*args, **kwargs) # NOTE(vponomaryov): parse existing extra specs # to str view for textarea html element es_str = "" for k, v in self.initial["extra_specs"].items(): es_str += "%s=%s\r\n" % (k, v) self.initial["extra_specs"] = es_str manila_features = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) self.enable_public_share_type_creation = manila_features.get( 'enable_public_share_type_creation', True) if not self.enable_public_share_type_creation: self.fields.pop('is_public') def handle(self, request, data): try: set_dict, unset_list = utils.parse_str_meta(data['extra_specs']) if set_dict: manila.share_type_set_extra_specs( request, self.initial["id"], set_dict) if unset_list: get = manila.share_type_get_extra_specs( request, self.initial["id"]) # NOTE(vponomaryov): skip keys that are already unset to_unset = set(unset_list).intersection(set(get.keys())) if to_unset: manila.share_type_unset_extra_specs( request, self.initial["id"], to_unset) name = data.get("name", None) description = data.get("description", None) is_public = (self.enable_public_share_type_creation and data.get("is_public", True)) manila.share_type_update( request, self.initial["id"], name, description, is_public) msg = _("Successfully updated share type '%s'.") msg = msg % self.initial['name'] messages.success(request, msg) return True except ValidationError as e: # handle error without losing dialog self.api_error(e.messages[0]) return False except Exception: msg = _("Unable to update share type.") exceptions.handle(request, msg) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/panel.py0000664000175000017500000000163700000000000024636 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class ShareTypes(horizon.Panel): name = _("Share Types") slug = 'share_types' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(ShareTypes) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/tables.py0000664000175000017500000000734700000000000025015 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import tables from manila_ui.api import manila def get_size(share): return _("%sGiB") % share.size class CreateShareType(tables.LinkAction): name = "create" verbose_name = _("Create Share Type") url = "horizon:admin:share_types:create_type" classes = ("ajax-modal", "btn-create") icon = "plus" class DeleteShareType(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Type", u"Delete Share Types", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Type", u"Deleted Share Types", count ) def delete(self, request, obj_id): manila.share_type_delete(request, obj_id) class ManageShareTypeAccess(tables.LinkAction): name = "manage" verbose_name = _("Manage Share Type Access") url = "horizon:admin:share_types:manage_share_type_access" classes = ("ajax-modal", "btn-create") def allowed(self, request, obj_id): st = manila.share_type_get(request, obj_id) # Enable it only for private share types return not st.is_public def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} class UpdateShareType(tables.LinkAction): name = "update share type" verbose_name = _("Update Share Type") url = "horizon:admin:share_types:update_type" classes = ("ajax-modal", "btn-create") def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} class ShareTypesFilterAction(tables.FilterAction): filter_type = "server" filter_choices = ( ('name', _("Name "), True), ('extra_specs', _("Extra Spec "), True), ) class ShareTypesTable(tables.DataTable): name = tables.WrappingColumn("name", verbose_name=_("Name")) description = tables.WrappingColumn( "description", verbose_name=_("Description")) extra_specs = tables.Column("extra_specs", verbose_name=_("Extra specs"), ) is_default = tables.Column( "is_default", verbose_name=_("Is default"), filters=(lambda d: 'Yes' if d is True else '-', ), ) visibility = tables.Column( "is_public", verbose_name=_("Visibility"), filters=(lambda d: 'public' if d is True else 'private', ), ) def get_object_display(self, share_type): return share_type.name def get_object_id(self, share_type): return str(share_type.id) class Meta(object): name = "share_types" verbose_name = _("Share Types") table_actions = ( ShareTypesFilterAction, CreateShareType, DeleteShareType, ) row_actions = ( UpdateShareType, ManageShareTypeAccess, DeleteShareType, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/0000775000175000017500000000000000000000000025154 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8066514 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/0000775000175000017500000000000000000000000027502 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/_create.html0000664000175000017500000000104300000000000031770 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "The share type defines the characteristics of a share backend." %}

Extra specs field:
{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add extra-specs use:" %}

key=value
{% trans "Extra spec 'driver_handles_share_servers' is required and should have boolean value." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/_manage_access.html0000664000175000017500000000324600000000000033305 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block form_id %}{% endblock %} {% block form_action %}{% url 'horizon:admin:share_types:manage_share_type_access' share_type.id %}{% endblock %} {% block modal_id %}manage_share_type_access_modal{% endblock %} {% block modal-header %}{% trans "Manage Share Type Access" %}{% endblock %} {% block modal-body %}
{% include "horizon/common/_form_fields.html" %}

{% trans "Description" %}:

{% blocktrans trimmed %} Placeholder for description of share type access managing form. {% endblocktrans %}

{% include "horizon/common/_form_fields.html" %}
{{ step.get_help_text }}
{% endblock %} {% block modal-footer %} {% trans "Cancel" %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/_update.html0000664000175000017500000000146100000000000032013 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can modify name, description, extra specs and visibility of a share type." %}

Extra specs field:
{% trans "Here can be modified extra-specs for share type." %}
{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add extra-specs use:" %}

key=value
{% trans "To unset extra-specs use:" %}
key
{% trans "All pairs that are in field for left are set for this share type." %} {% trans "Extra spec 'driver_handles_share_servers' is required and should have boolean value." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/create.html0000664000175000017500000000027500000000000031637 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share Type" %}{% endblock %} {% block main %} {% include 'admin/share_types/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/index.html0000664000175000017500000000034100000000000031475 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Types" %}{% endblock %} {% block main %}
{{ share_types_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/manage_access.html0000664000175000017500000000031300000000000033136 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Manage Share Type Access" %}{% endblock %} {% block main %} {% include 'admin/share_types/_manage_access.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/templates/share_types/update.html0000664000175000017500000000027500000000000031656 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Update Share Type" %}{% endblock %} {% block main %} {% include 'admin/share_types/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/urls.py0000664000175000017500000000223400000000000024516 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.share_types import views urlpatterns = [ re_path( r'^$', views.ShareTypesView.as_view(), name='index'), re_path( r'^create_type$', views.CreateShareTypeView.as_view(), name='create_type'), re_path( r'^update_type/(?P[^/]+)/extra_specs$', views.UpdateShareTypeView.as_view(), name='update_type'), re_path( r'^manage_share_type_access/(?P[^/]+)$', views.ManageShareTypeAccessView.as_view(), name='manage_share_type_access'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/views.py0000664000175000017500000001226300000000000024671 0ustar00zuulzuul00000000000000# 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. """ Admin views for managing share types. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon.utils import memoized from horizon import workflows from manila_ui.api import manila from manila_ui.dashboards.admin.share_types import forms as project_forms from manila_ui.dashboards.admin.share_types import tables as st_tables import manila_ui.dashboards.admin.share_types.workflows as st_workflows from manila_ui.dashboards import utils as common_utils class ShareTypesView(tables.MultiTableView): table_classes = ( st_tables.ShareTypesTable, ) template_name = "admin/share_types/index.html" page_title = _("Share Types") @memoized.memoized_method def get_share_types_data(self): try: share_types = manila.share_type_list(self.request) except Exception: exceptions.handle( self.request, _('Unable to retrieve share types.')) return [] # Convert dict with extra specs to friendly view for st in share_types: st.extra_specs = common_utils.metadata_to_str( st.extra_specs, 8, 45) share_types = self.get_filters(share_types) return share_types def get_filters(self, share_types): table = self._tables['share_types'] filters = self.get_server_filter_info(table.request, table) filter_string = filters['value'] filter_field = filters['field'] if filter_string and filter_field: filtered_data = [] for st in share_types: if filter_field == 'name': if st.name == filter_string: filtered_data.append(st) if filter_field == 'extra_specs': if filter_string in st.extra_specs: filtered_data.append(st) return filtered_data else: return share_types class CreateShareTypeView(forms.ModalFormView): form_class = project_forms.CreateShareType form_id = "create_share_type" template_name = 'admin/share_types/create.html' modal_header = _("Create Share Type") modal_id = "create_share_type_modal" submit_label = _("Create") submit_url = reverse_lazy("horizon:admin:share_types:create_type") success_url = reverse_lazy('horizon:admin:share_types:index') page_title = _("Create Share Type") class ManageShareTypeAccessView(workflows.WorkflowView): workflow_class = st_workflows.ManageShareTypeAccessWorkflow template_name = "admin/share_types/manage_access.html" success_url = 'horizon:project:share_types:index' page_title = _("Manage Share Type Access") def get_initial(self): return {'id': self.kwargs["share_type_id"]} def get_context_data(self, **kwargs): context = super(ManageShareTypeAccessView, self).get_context_data( **kwargs) context['id'] = self.kwargs['share_type_id'] return context class UpdateShareTypeView(forms.ModalFormView): form_class = project_forms.UpdateShareType form_id = "update_share_type" template_name = "admin/share_types/update.html" modal_header = _("Update Share Type") modal_id = "update_share_type_modal" submit_label = _("Update") submit_url = "horizon:admin:share_types:update_type" success_url = reverse_lazy("horizon:admin:share_types:index") page_title = _("Update Share Type") def get_object(self): if not hasattr(self, "_object"): st_id = self.kwargs["share_type_id"] try: self._object = manila.share_type_get(self.request, st_id) except Exception: msg = _("Unable to retrieve share_type.") url = reverse("horizon:admin:share_types:index") exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(UpdateShareTypeView, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): share_type = self.get_object() st_info = { "id": self.kwargs["share_type_id"], "name": share_type.name, "extra_specs": share_type.extra_specs, "is_public": share_type.is_public, } if hasattr(share_type, 'description'): st_info['description'] = share_type.description return st_info ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/share_types/workflows.py0000664000175000017500000001045400000000000025571 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import workflows from openstack_dashboard.api import keystone from manila_ui.api import manila class AddProjectAction(workflows.MembershipAction): def __init__(self, request, *args, **kwargs): super(AddProjectAction, self).__init__(request, *args, **kwargs) default_role_field_name = self.get_default_role_field_name() self.fields[default_role_field_name] = forms.CharField(required=False) self.fields[default_role_field_name].initial = 'member' field_name = self.get_member_field_name('member') self.fields[field_name] = forms.MultipleChoiceField(required=False) share_type_id = self.initial['id'] # Get list of existing projects try: projects, __ = keystone.tenant_list(request) except Exception: err_msg = _('Unable to get list of projects.') exceptions.handle(request, err_msg) # Get list of projects with access to this Share Type try: share_type = manila.share_type_get(request, share_type_id) self.share_type_name = share_type.name projects_initial = manila.share_type_access_list( request, share_type) except Exception: err_msg = _('Unable to get information about share type access.') exceptions.handle(request, err_msg) self.fields[field_name].choices = [ (project.id, project.name or project.id) for project in projects] self.fields[field_name].initial = [ pr.project_id for pr in projects_initial] self.projects_initial = set(self.fields[field_name].initial) class Meta(object): name = _("Projects with access to share type") slug = "update_members" def handle(self, request, context): context.update({ 'name': self.share_type_name, 'projects_add': self.projects_allow - self.projects_initial, 'projects_remove': self.projects_initial - self.projects_allow, }) return context def clean(self): cleaned_data = super(AddProjectAction, self).clean() self.projects_allow = set( cleaned_data[self.get_member_field_name('member')]) return cleaned_data class AddProjectStep(workflows.UpdateMembersStep): action_class = AddProjectAction available_list_title = _("Available projects") help_text = _("Allow project access to share type.") members_list_title = _("Selected projects") no_available_text = _("No projects found.") no_members_text = _("No projects selected.") depends_on = ("id", ) show_roles = False class ManageShareTypeAccessWorkflow(workflows.Workflow): slug = "manage_share_type_access" name = _("Manage Share Type Access") finalize_button_name = _("Manage Share Type Access") success_message = _('Updated access for share type "%s".') failure_message = _('Unable to update access for share type "%s".') success_url = 'horizon:admin:share_types:index' default_steps = (AddProjectStep, ) def format_status_message(self, message): return message % self.context['name'] def handle(self, request, context): try: for project in self.context['projects_remove']: manila.share_type_access_remove( request, self.context['id'], project) for project in self.context['projects_add']: manila.share_type_access_add( request, self.context['id'], project) return True except Exception: exceptions.handle(request, _('Unable to update share type.')) return False ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8066514 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/0000775000175000017500000000000000000000000022115 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/__init__.py0000664000175000017500000000000000000000000024214 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/forms.py0000664000175000017500000003200400000000000023614 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. from django.conf import settings from django.forms import ValidationError from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from oslo_utils import strutils from manila_ui.api import manila from manila_ui.dashboards import utils def _get_id_if_name_empty(data): result = data.get('name', None) if not result: result = data.get('id') if not result: result = '' return result class MigrationStart(forms.SelfHandlingForm): name = forms.CharField( label=_("Share Name"), widget=forms.TextInput(attrs={'readonly': 'readonly'})) share_id = forms.CharField( label=_("ID"), widget=forms.TextInput(attrs={'readonly': 'readonly'})) host = forms.ChoiceField( label=_("Host to migrate share"), help_text=_("Destination host and pool where share will be migrated " "to.")) force_host_assisted_migration = forms.BooleanField( label=_("Force Host Assisted Migration"), required=False, initial=False, help_text=_("Enforces the use of the host-assisted migration approach," " which bypasses driver optimizations.")) nondisruptive = forms.BooleanField( label=_("Nondisruptive"), required=False, initial=True, help_text=_("Enforces migration to be nondisruptive. If set to True, " "host-assisted migration will not be attempted.")) writable = forms.BooleanField( label=_("Writable"), required=False, initial=True, help_text=_("Enforces migration to keep the share writable while " "contents are being moved. If set to True, host-assisted " "migration will not be attempted.")) preserve_metadata = forms.BooleanField( label=_("Preserve Metadata"), required=False, initial=True, help_text=_("Enforces migration to preserve all file metadata when " "moving its contents. If set to True, host-assisted " "migration will not be attempted.")) preserve_snapshots = forms.BooleanField( label=_("Preserve Snapshots"), required=False, initial=True, help_text=_("Enforces migration of the share snapshots to the " "destination. If set to True, host-assisted migration will" " not be attempted.")) new_share_network = forms.ChoiceField( label=_("New share network to be set in migrated share"), required=False, help_text=_('Specify the new share network for the share. Do not ' 'specify this parameter if the migrating share has to be ' 'retained within its current share network.')) new_share_type = forms.ChoiceField( label=_("New share type to be set in migrating share"), required=False, help_text=_('Specify the new share type for the share. Do not specify ' 'this parameter if the migrating share has to be retained ' 'with its current share type.')) def __init__(self, request, *args, **kwargs): super(MigrationStart, self).__init__(request, *args, **kwargs) share_networks = manila.share_network_list(request) share_types = manila.share_type_list(request) dests = manila.pool_list(request) dest_choices = [('', '')] + [(d.name, d.name) for d in dests] st_choices = [('', '')] + [(st.id, st.name) for st in share_types] sn_choices = ( [('', '')] + [(sn.id, sn.name or sn.id) for sn in share_networks]) self.fields['host'].choices = dest_choices self.fields['new_share_type'].choices = st_choices self.fields['new_share_network'].choices = sn_choices def handle(self, request, data): share_name = _get_id_if_name_empty(data) try: manila.migration_start( request, self.initial['share_id'], force_host_assisted_migration=( data['force_host_assisted_migration']), writable=data['writable'], preserve_metadata=data['preserve_metadata'], preserve_snapshots=data['preserve_snapshots'], nondisruptive=data['nondisruptive'], dest_host=data['host'], new_share_network_id=data['new_share_network'], new_share_type_id=data['new_share_type']) messages.success( request, _('Successfully sent the request to migrate share: %s.') % share_name) return True except Exception: redirect = reverse("horizon:admin:shares:index") exceptions.handle( request, _("Unable to migrate share %s.") % share_name, redirect=redirect) return False class MigrationForms(forms.SelfHandlingForm): name = forms.CharField( label=_("Share Name"), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) share_id = forms.CharField( label=_("ID"), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) class MigrationComplete(MigrationForms): def handle(self, request, data): share_name = _get_id_if_name_empty(data) try: manila.migration_complete(request, self.initial['share_id']) messages.success( request, _('Successfully sent the request to complete migration of ' ' share: %s.') % share_name) return True except Exception: exceptions.handle(request, _("Unable to complete migration " "of share %s.") % share_name) return False class MigrationGetProgress(MigrationForms): def handle(self, request, data): share_name = _get_id_if_name_empty(data) try: result = manila.migration_get_progress(request, self.initial['share_id']) progress = result[1] messages.success( request, _('Migration of share %(name)s is at %(progress)s percent.') % {'name': share_name, 'progress': progress['total_progress']}) return True except Exception: exceptions.handle(request, _("Unable to obtain progress of " "migration of share %s at this " "moment.") % share_name) return False class MigrationCancel(MigrationForms): def handle(self, request, data): share_name = _get_id_if_name_empty(data) try: manila.migration_cancel(request, self.initial['share_id']) messages.success( request, _('Successfully sent the request to cancel migration of ' ' share: %s.') % share_name) return True except Exception: exceptions.handle(request, _("Unable to cancel migration of share" " %s at this moment.") % share_name) return False class ManageShare(forms.SelfHandlingForm): name = forms.CharField( max_length=255, label=_("Share Name"), required=False, help_text=_("Share name to be assigned")) description = forms.CharField( max_length=255, label=_("Description"), required=False, widget=forms.Textarea( attrs={'class': 'modal-body-fixed-width', 'rows': 4})) host = forms.CharField( max_length=255, label=_("Host of share"), required=True, help_text=_( "Host where share is located, example: some.host@driver[#pool]")) export_location = forms.CharField( max_length=255, label=_("Export location"), required=True, help_text=_("Export location of share. Example for NFS: " "1.2.3.4:/path/to/share")) protocol = forms.ChoiceField(label=_("Share Protocol"), required=True) share_type = forms.ChoiceField(label=_("Share Type"), required=True) driver_options = forms.CharField( max_length=255, required=False, label=_("Driver options ('volume_id' for Generic driver, etc...)"), help_text=_("key=value pairs per line can be set"), widget=forms.Textarea( attrs={'class': 'modal-body-fixed-width', 'rows': 2})) is_public = forms.BooleanField( label=_("Public"), required=False, initial=False, help_text=("Defines whether this share is available for all or not.")) def __init__(self, request, *args, **kwargs): super(ManageShare, self).__init__(request, *args, **kwargs) share_types = manila.share_type_list(request) # NOTE(vponomaryov): choose only those share_types that have spec # 'driver_handles_share_servers' set to 'False' value or alias of it. dhss_key = 'driver_handles_share_servers' st_choices = [('', ''), ] for st in share_types: dhss = st.to_dict()['extra_specs'].get(dhss_key) if dhss and dhss.lower() in strutils.FALSE_STRINGS: st_choices.append((st.name, st.name)) self.fields['share_type'].choices = st_choices # NOTE(vkmc): choose only those share protocols that are enabled # FIXME(vkmc): this should be better implemented by having a # capabilities endpoint on the control plane. manila_features = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) self.enabled_share_protocols = manila_features.get( 'enabled_share_protocols', ['NFS', 'CIFS', 'GlusterFS', 'HDFS', 'CephFS', 'MapRFS']) self.fields['protocol'].choices = ([(' ', ' ')] + [(enabled_proto, enabled_proto) for enabled_proto in self.enabled_share_protocols]) def handle(self, request, data): try: driver_options = data.get('driver_options') or {} driver_options_error_msg = _( "Got improper value for field 'driver_options'. " "Expected only pairs of key=value.") if driver_options and isinstance(driver_options, str): try: set_dict, unset_list = utils.parse_str_meta(driver_options) if unset_list: raise ValidationError(message=driver_options_error_msg) driver_options = set_dict except ValidationError as e: self.api_error(e.messages[0]) return False elif not isinstance(driver_options, dict): self.api_error(driver_options_error_msg) return False manila.share_manage( request, service_host=data['host'], protocol=data['protocol'], export_path=data['export_location'], driver_options=driver_options, share_type=data['share_type'], name=data['name'], description=data['description'], is_public=data['is_public']) share_name = data.get('name', data.get('id')) messages.success( request, _('Successfully sent the request to manage share: %s') % share_name) return True except Exception: exceptions.handle(request, _("Unable to manage share")) return False class UnmanageShare(forms.SelfHandlingForm): name = forms.CharField( label=_("Share Name"), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) host = forms.CharField( label=_("Host"), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) share_id = forms.CharField( label=_("ID"), required=False, widget=forms.TextInput(attrs={'readonly': 'readonly'})) def handle(self, request, data): try: manila.share_unmanage(request, self.initial['share_id']) messages.success( request, _('Successfully sent the request to unmanage share: %s') % data['name']) return True except Exception: exceptions.handle(request, _("Unable to unmanage share.")) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/panel.py0000664000175000017500000000156000000000000023570 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class Shares(horizon.Panel): name = _("Shares") slug = "shares" permissions = ( 'openstack.services.share', ) dashboard.Admin.register(Shares) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8066514 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/replicas/0000775000175000017500000000000000000000000023717 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/replicas/__init__.py0000664000175000017500000000000000000000000026016 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/replicas/forms.py0000664000175000017500000000750300000000000025424 0ustar00zuulzuul00000000000000# Copyright (c) 2016 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class ResyncReplicaForm(forms.SelfHandlingForm): def handle(self, request, data): replica_id = self.initial['replica_id'] try: replica = manila.share_replica_get(self.request, replica_id) manila.share_replica_resync(request, replica) message = _("Resync'ing replica '%s'") % replica_id messages.success(request, message) return True except Exception: redirect = reverse("horizon:admin:shares:index") exceptions.handle( request, _("Unable to resync replica '%s'.") % replica_id, redirect=redirect) class ResetReplicaStatusForm(forms.SelfHandlingForm): replica_status = forms.ChoiceField( label=_("Replica State"), required=True, choices=( ('available', 'available'), ('creating', 'creating'), ('deleting', 'deleting'), ('error', 'error'), ) ) def handle(self, request, data): replica_id = self.initial['replica_id'] try: replica = manila.share_replica_get(self.request, replica_id) manila.share_replica_reset_status( request, replica, data["replica_status"]) message = _("Reseting replica ('%(id)s') status from '%(from)s' " "to '%(to)s'.") % { "id": replica_id, "from": replica.replica_state, "to": data["replica_status"]} messages.success(request, message) return True except Exception: redirect = reverse("horizon:admin:shares:index") exceptions.handle( request, _("Unable to reset status of replica '%s'.") % replica_id, redirect=redirect) class ResetReplicaStateForm(forms.SelfHandlingForm): replica_state = forms.ChoiceField( label=_("Replica State"), required=True, choices=( ('active', 'active'), ('in_sync', 'in_sync'), ('out_of_sync', 'out_of_sync'), ('error', 'error'), ) ) def handle(self, request, data): replica_id = self.initial['replica_id'] try: replica = manila.share_replica_get(self.request, replica_id) manila.share_replica_reset_state( request, replica, data["replica_state"]) message = _("Reseting replica ('%(id)s') state from '%(from)s' " "to '%(to)s'.") % { "id": replica_id, "from": replica.replica_state, "to": data["replica_state"]} messages.success(request, message) return True except Exception: redirect = reverse("horizon:admin:shares:index") exceptions.handle( request, _("Unable to reset state of replica '%s'.") % replica_id, redirect=redirect) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/replicas/tables.py0000664000175000017500000001203400000000000025543 0ustar00zuulzuul00000000000000# Copyright (c) 2016 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import messages from horizon import tables from manila_ui.api import manila from manila_ui.dashboards.project.shares.replicas import ( tables as replica_tables) DELETABLE_STATUSES = ("error", "available") class UpdateReplicaRow(tables.Row): ajax = True def get_data(self, request, replica_id): replica = manila.share_replica_get(request, replica_id) return replica class ResyncReplica(tables.LinkAction): name = "resync_replica" verbose_name = _("Resync replica") url = "horizon:admin:shares:resync_replica" classes = ("ajax-modal", "btn-create") policy_rules = (("share_replica", "share_replica:resync"),) def allowed(self, request, replica=None): return True def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def get_link_url(self, replica): return reverse(self.url, args=(replica.id,)) class ResetReplicaState(tables.LinkAction): name = "reset_replica_state" verbose_name = _("Reset replica state") url = "horizon:admin:shares:reset_replica_state" classes = ("ajax-modal", "btn-create") policy_rules = (("share_replica", "share_replica:reset_replica_state"),) def allowed(self, request, replica=None): return True def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def get_link_url(self, replica): return reverse(self.url, args=(replica.id,)) class ResetReplicaStatus(tables.LinkAction): name = "reset_replica_status" verbose_name = _("Reset replica status") url = "horizon:admin:shares:reset_replica_status" classes = ("ajax-modal", "btn-create") policy_rules = (("share_replica", "share_replica:reset_status"),) def allowed(self, request, replica=None): return True def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def get_link_url(self, replica): return reverse(self.url, args=(replica.id,)) class DeleteReplica(tables.DeleteAction): policy_rules = (("share_replica", "share_replica:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Replica", u"Delete Replicas", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Replica", u"Deleted Replicas", count ) def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def delete(self, request, obj_id): try: manila.share_replica_delete(request, obj_id) except Exception: msg = _('Unable to delete replica "%s".') % obj_id messages.error(request, msg) def allowed(self, request, replica=None): if replica: share = manila.share_get(request, replica.share_id) replicas = manila.share_replica_list(request, replica.share_id) if share.replication_type is None: return False elif (share.replication_type == 'writable' and replica.status in DELETABLE_STATUSES and len(replicas) > 1) or ( share.replication_type in ('dr', 'readable') and replica.status in DELETABLE_STATUSES and replica.replica_state != 'active'): return True return False def single(self, data_table, request, object_id): try: manila.share_replica_delete(request, object_id) messages.success( request, _('Share replica %s has been deleted.') % object_id) except Exception: msg = _('Unable to delete replica "%s".') % object_id messages.error(request, msg) _DETAIL_URL = "horizon:admin:shares:replica_detail" class ReplicasTable(replica_tables.ReplicasTable): class Meta(object): name = "replicas" verbose_name = _("Replicas") status_columns = ("status",) row_class = UpdateReplicaRow row_actions = ( ResyncReplica, ResetReplicaState, ResetReplicaStatus, DeleteReplica) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/replicas/tabs.py0000664000175000017500000000206100000000000025221 0ustar00zuulzuul00000000000000# Copyright (c) 2016 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ReplicaOverviewTab(tabs.Tab): name = _("Overview") slug = "overview" template_name = "admin/shares/replicas/_detail_overview.html" def get_context_data(self, request): return {"replica": self.tab_group.kwargs['replica']} class ReplicaDetailTabs(tabs.TabGroup): slug = "replica_details" tabs = (ReplicaOverviewTab,) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/replicas/views.py0000664000175000017500000001363100000000000025432 0ustar00zuulzuul00000000000000# Copyright (c) 2016 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from manila_ui.api import manila from manila_ui.dashboards.admin.shares.replicas import ( tables as replicas_tables) from manila_ui.dashboards.admin.shares.replicas import forms as replicas_forms from manila_ui.dashboards.admin.shares.replicas import tabs as replicas_tabs from manila_ui.dashboards.project.shares.replicas import ( views as project_replica_views) class ManageReplicasView(project_replica_views.ManageReplicasView): table_class = replicas_tables.ReplicasTable template_name = 'admin/shares/replicas/manage_replicas.html' _redirect_url = 'horizon:admin:shares:index' class DetailReplicaView(project_replica_views.DetailReplicaView): tab_group_class = replicas_tabs.ReplicaDetailTabs template_name = 'admin/shares/replicas/detail.html' _redirect_url = 'horizon:admin:shares:index' class ResyncReplicaView(forms.ModalFormView): form_class = replicas_forms.ResyncReplicaForm form_id = "resync_replica" template_name = 'admin/shares/replicas/resync_replica.html' modal_header = _("Resync Replica") modal_id = "resync_replica_modal" submit_label = _("Resync") submit_url = "horizon:admin:shares:resync_replica" success_url = 'horizon:admin:shares:manage_replicas' page_title = _("Resync Replica") def get_success_url(self): return reverse(self.success_url, args=[self.get_object().share_id]) def get_object(self): if not hasattr(self, "_object"): replica_id = self.kwargs["replica_id"] try: self._object = manila.share_replica_get( self.request, replica_id) except Exception: msg = _("Unable to retrieve replica '%s'.") % replica_id url = reverse('horizon:admin:shares:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) context['replica_id'] = self.kwargs['replica_id'] args = (context['replica_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): return {'replica_id': self.kwargs["replica_id"]} class ResetReplicaStatusView(forms.ModalFormView): form_class = replicas_forms.ResetReplicaStatusForm form_id = "reset_replica_status" template_name = 'admin/shares/replicas/reset_replica_status.html' modal_header = _("Reset Replica Status") modal_id = "reset_replica_status_modal" submit_label = _("Reset status") submit_url = "horizon:admin:shares:reset_replica_status" success_url = 'horizon:admin:shares:manage_replicas' page_title = _("Reset Replica Status") def get_success_url(self): return reverse(self.success_url, args=[self.get_object().share_id]) def get_object(self): if not hasattr(self, "_object"): replica_id = self.kwargs["replica_id"] try: self._object = manila.share_replica_get( self.request, replica_id) except Exception: msg = _("Unable to retrieve replica '%s'.") % replica_id url = reverse('horizon:admin:shares:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) context['replica_id'] = self.kwargs['replica_id'] args = (context['replica_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): return {'replica_id': self.kwargs["replica_id"]} class ResetReplicaStateView(forms.ModalFormView): form_class = replicas_forms.ResetReplicaStateForm form_id = "reset_replica_state" template_name = 'admin/shares/replicas/reset_replica_state.html' modal_header = _("Reset Replica State") modal_id = "reset_replica_state_modal" submit_label = _("Reset state") submit_url = "horizon:admin:shares:reset_replica_state" success_url = 'horizon:admin:shares:manage_replicas' page_title = _("Reset Replica State") def get_success_url(self): return reverse(self.success_url, args=[self.get_object().share_id]) def get_object(self): if not hasattr(self, "_object"): replica_id = self.kwargs["replica_id"] try: self._object = manila.share_replica_get( self.request, replica_id) except Exception: msg = _("Unable to retrieve replica '%s'.") % replica_id url = reverse('horizon:admin:shares:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) context['replica_id'] = self.kwargs['replica_id'] args = (context['replica_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): return {'replica_id': self.kwargs["replica_id"]} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/tables.py0000664000175000017500000001265600000000000023753 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import tables from manila_ui.dashboards.project.shares import tables as shares_tables from manila_ui import features class MigrationStartAction(tables.LinkAction): name = "migration_start" verbose_name = _("Migrate Share") url = "horizon:admin:shares:migration_start" classes = ("ajax-modal",) policy_rules = (("share", "migration_start"),) ajax = True def allowed(self, request, share=None): if share: return (share.status.upper() == "AVAILABLE" and not getattr(share, 'has_snapshot', False) and features.is_migration_enabled()) return False class MigrationCompleteAction(tables.LinkAction): name = "migration_complete" verbose_name = _("Complete migration") url = "horizon:admin:shares:migration_complete" classes = ("ajax-modal",) policy_rules = (("share", "migration_complete"),) ajax = True def allowed(self, request, share=None): if (share and share.status.upper() == "MIGRATING" and features.is_migration_enabled()): return True return False class MigrationCancelAction(tables.LinkAction): name = "migration_cancel" verbose_name = _("Cancel migration") url = "horizon:admin:shares:migration_cancel" classes = ("ajax-modal",) policy_rules = (("share", "migration_cancel"),) ajax = True def allowed(self, request, share=None): if (share and share.status.upper() == "MIGRATING" and features.is_migration_enabled()): return True return False class MigrationGetProgressAction(tables.LinkAction): name = "migration_get_progress" verbose_name = _("Get migration progress") url = "horizon:admin:shares:migration_get_progress" classes = ("ajax-modal",) policy_rules = (("share", "migration_get_progress"),) ajax = True def allowed(self, request, share=None): if (share and share.status.upper() == "MIGRATING" and features.is_migration_enabled()): return True return False class ManageShareAction(tables.LinkAction): name = "manage" verbose_name = _("Manage Share") url = "horizon:admin:shares:manage" classes = ("ajax-modal",) icon = "plus" policy_rules = (("share", "share_extension:share_manage"),) ajax = True class UnmanageShareAction(tables.LinkAction): name = "unmanage" verbose_name = _("Unmanage Share") url = "horizon:admin:shares:unmanage" classes = ("ajax-modal",) icon = "pencil" policy_rules = (("share", "share_extension:share_unmanage"),) def allowed(self, request, share=None): if (not share or share.share_server_id or share.status.upper() not in shares_tables.DELETABLE_STATES): return False elif hasattr(share, 'has_snapshot'): return not share.has_snapshot return False class ManageReplicas(tables.LinkAction): name = "manage_replicas" verbose_name = _("Manage Replicas") url = "horizon:admin:shares:manage_replicas" classes = ("btn-edit",) policy_rules = (("share", "share:replica_get_all"),) def allowed(self, request, share): share_replication_enabled = share.replication_type is not None return features.is_replication_enabled() and share_replication_enabled class SharesTable(shares_tables.SharesTable): name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:admin:shares:detail") host = tables.Column("host", verbose_name=_("Host")) project = tables.Column("project_name", verbose_name=_("Project")) def get_share_server_link(share): if getattr(share, 'share_server_id', None): return reverse("horizon:admin:share_servers:share_server_detail", args=(share.share_server_id,)) else: return None share_server = tables.Column( "share_server_id", verbose_name=_("Share Server"), link=get_share_server_link) class Meta(object): name = "shares" verbose_name = _("Shares") status_columns = ["status"] row_class = shares_tables.UpdateRow table_actions = ( tables.NameFilterAction, ManageShareAction, shares_tables.DeleteShare, ) row_actions = ( ManageReplicas, MigrationStartAction, MigrationCompleteAction, MigrationGetProgressAction, MigrationCancelAction, UnmanageShareAction, shares_tables.DeleteShare, ) columns = [ 'tenant', 'host', 'name', 'size', 'status', 'visibility', 'share_type', 'protocol', 'share_server', ] if features.is_share_groups_enabled(): columns.append('share_group_id') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/tabs.py0000664000175000017500000000202500000000000023417 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareOverviewTab(tabs.Tab): name = _("Share Overview") slug = "share_overview_tab" template_name = "admin/shares/_detail.html" def get_context_data(self, request): return {"share": self.tab_group.kwargs["share"]} class ShareDetailTabs(tabs.TabGroup): slug = "share_details" tabs = ( ShareOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/0000775000175000017500000000000000000000000024113 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/0000775000175000017500000000000000000000000025400 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_detail.html0000664000175000017500000000755600000000000027704 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Overview" %}


{% trans "Name" %}
{{ share.name }}
{% trans "ID" %}
{{ share.id }}
{% if share.description %}
{% trans "Description" %}
{{ share.description }}
{% endif %}
{% trans "Status" %}
{{ share.status|capfirst }}
{% trans "Export locations" %}
{% for el in share.export_locations %}

{% trans "Path:" %}
{% trans "Preferred:" %} {{ el.preferred }}
{% if el.is_admin_only == True or el.is_admin_only == False %}
{% trans "Is admin only:" %} {{ el.is_admin_only }}
{% endif %} {% if el.share_instance_id %}
{% trans "Share Replica ID:" %} {{ el.share_instance_id }}
{% endif %}

{% endfor %} {% if share.snapshot_id %}
{% trans "Snapshot ID" %}
{% url 'horizon:admin:share_snapshots:snapshot_detail' share.snapshot_id as snapshot_url%}
{{ share.snapshot_id }}
{% endif %}
{% trans "Visibility" %}
{% if share.is_public == True %}
{{ 'public' }}
{% else %}
{{ 'private' }}
{% endif %}
{% trans "Availability zone" %}
{{ share.availability_zone }}
{% trans "Size" %}
{{ share.size }} {% trans "GiB" %}
{% trans "Protocol" %}
{{ share.share_proto }}
{% if share.share_type %}
{% trans "Share type" %}

{% trans "Name:" %} {{ share.share_type_name }}
{% trans "ID:" %} {{ share.share_type }}

{% endif %} {% if share.share_network_id %}
{% trans "Share Network" %}
{% url 'horizon:admin:share_networks:share_network_detail' share.share_network_id as sn_url%}
{{ share.share_network_id }}
{% endif %} {% if share.share_group_id %}
{% trans "Share Group" %}
{% url 'horizon:admin:share_groups:detail' share.share_group_id as sg_url%}
{{ share.share_group_id }}
{% endif %}
{% trans "Mount snapshot support" %}
{{ share.mount_snapshot_support }}
{% trans "Created" %}
{{ share.created_at|parse_date }}
{% trans "Host" %}
{{ share.host }}
{% trans "Task state" %}
{{ share.task_state }}

{% trans "Access Rules" %}


{% for rule in share.rules %}
{{ rule.access_type }}

{% trans "Access to:" %} {{ rule.access_to }}
{% trans "Access Level:" %} {{ rule.access_level }}
{% trans "Status:" %} {{ rule.state }}
{% trans "Access Key:" %} {{ rule.access_key }}
{% trans "Created At:" %} {{ rule.created_at|parse_date }}
{% trans "Updated At:" %} {{ rule.updated_at|parse_date }}

{% endfor %}

{% trans "Metadata" %}


{% for key, value in share.metadata.items %}
{{ key }}
{{ value }}
{% endfor %}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_manage_share.html0000664000175000017500000000061300000000000031037 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description:" %}

{% blocktrans trimmed %} "Manage" an existing share from a Manila host. This will make the share visible within OpenStack.

This is equivalent to the 'manila manage' command. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_migration_cancel.html0000664000175000017500000000052700000000000031727 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description:" %}

{% blocktrans trimmed %} Cancel migration of a migrating share.

This is equivalent to the 'manila migration-cancel' command. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_migration_complete.html0000664000175000017500000000064300000000000032311 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description:" %}

{% blocktrans trimmed %} Complete migration of a migrating share to another Manila host. This operation is expected to be disruptive.

This is equivalent to the 'manila migration-complete' command. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_migration_get_progress.html0000664000175000017500000000054700000000000033207 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description:" %}

{% blocktrans trimmed %} Obtains migration progress of a migrating share.

This is equivalent to the 'manila migration-get-progress' command. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_migration_start.html0000664000175000017500000000064200000000000031635 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description:" %}

{% blocktrans trimmed %} Migrate an existing share to another Manila host. This will move all your share data from one host to another.

This is equivalent to the 'manila migration-start' command. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/_unmanage_share.html0000664000175000017500000000064700000000000031411 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description:" %}

{% blocktrans trimmed %} When a share is "unmanaged", the share will no longer be visible within OpenStack. Note that the share will not be deleted.

This is equivalent to the 'manila unmanage' command. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/detail.html0000664000175000017500000000033300000000000027527 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/index.html0000664000175000017500000000032700000000000027377 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Shares" %}{% endblock %} {% block main %}
{{ shares_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/manage_share.html0000664000175000017500000000027100000000000030700 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Manage Share" %}{% endblock %} {% block main %} {% include 'admin/shares/_manage_share.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/migration_cancel.html0000664000175000017500000000030100000000000031556 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Cancel Migration" %}{% endblock %} {% block main %} {% include 'admin/shares/_migration_cancel.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/migration_complete.html0000664000175000017500000000030500000000000032145 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Complete Migration" %}{% endblock %} {% block main %} {% include 'admin/shares/_migration_complete.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/migration_get_progress.html0000664000175000017500000000031500000000000033041 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Get Migration Progress" %}{% endblock %} {% block main %} {% include 'admin/shares/_migration_get_progress.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/migration_start.html0000664000175000017500000000027500000000000031500 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Migrate Share" %}{% endblock %} {% block main %} {% include 'admin/shares/_migration_start.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/0000775000175000017500000000000000000000000027202 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/_detail_overview.html0000664000175000017500000000271000000000000033417 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Replica Overview" %}


{% trans "ID" %}
{{ replica.id }}
{% trans "Share" %}
{% url 'horizon:admin:shares:detail' replica.share_id as share_url%}
{{ replica.share_id }}
{% trans "Status" %}
{{ replica.status|capfirst }}
{% trans "Replica state" %}
{{ replica.replica_state|capfirst }}
{% trans "Export locations" %}
{% for el in replica.export_locations %}

Path:
Preferred: {{ el.preferred }}
{% if el.is_admin_only == True or el.is_admin_only == False %}
Is admin only: {{ el.is_admin_only }}
{% endif %}

{% endfor %}
{% trans "Availability zone" %}
{{ replica.availability_zone }}
{% trans "Created" %}
{{ replica.created_at|parse_date }}
{% trans "Updated" %}
{{ replica.updated_at|parse_date }}
{% trans "Host" %}
{{ replica.host }}
././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/_reset_replica_state.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/_reset_replica_state.ht0000664000175000017500000000030300000000000033713 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Reset share replica's state with ID" %} "{{ replica_id }}"

{% endblock %} ././@PaxHeader0000000000000000000000000000020700000000000011454 xustar0000000000000000113 path=manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/_reset_replica_status.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/_reset_replica_status.h0000664000175000017500000000030400000000000033733 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Reset share replica's status with ID" %} "{{ replica_id }}"

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/_resync_replica.html0000664000175000017500000000026700000000000033236 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body %}

{% trans "Resync share replica with ID" %} "{{ replica_id }}"?

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/detail.html0000664000175000017500000000033500000000000031333 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Replica Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/manage_replicas.html0000664000175000017500000000023400000000000033201 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Replicas" %}{% endblock %} {% block main %} {{ table.render }} {% endblock %} ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/reset_replica_state.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/reset_replica_state.htm0000664000175000017500000000032000000000000033730 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Reset Replica State" %}{% endblock %} {% block main %} {% include 'admin/shares/replicas/_reset_replica_state.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/reset_replica_status.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/reset_replica_status.ht0000664000175000017500000000032200000000000033760 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Reset Replica Status" %}{% endblock %} {% block main %} {% include 'admin/shares/replicas/_reset_replica_status.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/replicas/resync_replica.html0000664000175000017500000000030600000000000033071 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Resync Replica" %}{% endblock %} {% block main %} {% include 'admin/shares/replicas/_resync_replica.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/templates/shares/unmanage_share.html0000664000175000017500000000027500000000000031247 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Unmanage Share" %}{% endblock %} {% block main %} {% include 'admin/shares/_unmanage_share.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/urls.py0000664000175000017500000000542100000000000023456 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.shares.replicas import views as replica_views from manila_ui.dashboards.admin.shares import views from manila_ui import features urlpatterns = [ re_path( r'^$', views.SharesView.as_view(), name='index'), re_path( r'^(?P[^/]+)/$', views.DetailView.as_view(), name='detail'), re_path( r'^manage$', views.ManageShareView.as_view(), name='manage'), re_path( r'^unmanage/(?P[^/]+)$', views.UnmanageShareView.as_view(), name='unmanage'), ] if features.is_replication_enabled(): urlpatterns.extend([ re_path( r'^(?P[^/]+)/replicas/$', replica_views.ManageReplicasView.as_view(), name='manage_replicas'), re_path( r'^replica/(?P[^/]+)$', replica_views.DetailReplicaView.as_view(), name='replica_detail'), re_path( r'^replica/(?P[^/]+)/resync_replica$', replica_views.ResyncReplicaView.as_view(), name='resync_replica'), re_path( r'^replica/(?P[^/]+)/reset_replica_status$', replica_views.ResetReplicaStatusView.as_view(), name='reset_replica_status'), re_path( r'^replica/(?P[^/]+)/reset_replica_state$', replica_views.ResetReplicaStateView.as_view(), name='reset_replica_state'), ]) if features.is_migration_enabled(): urlpatterns.extend([ re_path( r'^migration_start/(?P[^/]+)$', views.MigrationStartView.as_view(), name='migration_start'), re_path( r'^migration_complete/(?P[^/]+)$', views.MigrationCompleteView.as_view(), name='migration_complete'), re_path( r'^migration_cancel/(?P[^/]+)$', views.MigrationCancelView.as_view(), name='migration_cancel'), re_path( r'^migration_get_progress/(?P[^/]+)$', views.MigrationGetProgressView.as_view(), name='migration_get_progress'), ]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/shares/views.py0000664000175000017500000002367600000000000023642 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Admin views for managing shares. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.shares import forms as project_forms from manila_ui.dashboards.admin.shares import tables as s_tables from manila_ui.dashboards.admin.shares import tabs as s_tabs from manila_ui.dashboards.admin import utils from manila_ui.dashboards.project.shares import views as share_views class SharesView(tables.MultiTableView, share_views.ShareTableMixIn): table_classes = ( s_tables.SharesTable, ) template_name = "admin/shares/index.html" page_title = _("Shares") @memoized.memoized_method def get_shares_data(self): shares = [] try: shares = manila.share_list( self.request, search_opts={'all_tenants': True}) snapshots = manila.share_snapshot_list( self.request, detailed=True, search_opts={'all_tenants': True}) share_ids_with_snapshots = [] for snapshot in snapshots: share_ids_with_snapshots.append(snapshot.to_dict()['share_id']) for share in shares: if share.to_dict()['id'] in share_ids_with_snapshots: setattr(share, 'has_snapshot', True) else: setattr(share, 'has_snapshot', False) except Exception: exceptions.handle( self.request, _('Unable to retrieve share list.')) # Gather our projects to correlate against IDs utils.set_project_name_to_objects(self.request, shares) return shares class DetailView(share_views.DetailView): tab_group_class = s_tabs.ShareDetailTabs template_name = "admin/shares/detail.html" def get_context_data(self, **kwargs): context = super(DetailView, self).get_context_data(**kwargs) context["page_title"] = _("Share Details: %(share_name)s") % { 'share_name': context["share_display_name"]} return context class ManageShareView(forms.ModalFormView): form_class = project_forms.ManageShare form_id = "manage_share" template_name = 'admin/shares/manage_share.html' modal_header = _("Manage Share") modal_id = "manage_share_modal" submit_label = _("Manage") success_url = reverse_lazy('horizon:admin:shares:index') submit_url = reverse_lazy('horizon:admin:shares:manage') page_title = _("Manage Share") def get_context_data(self, **kwargs): context = super(ManageShareView, self).get_context_data(**kwargs) return context class MigrationStartView(forms.ModalFormView): form_class = project_forms.MigrationStart template_name = 'admin/shares/migration_start.html' modal_header = _("Migrate Share") form_id = "migration_start_share" modal_id = "migration_start_share_modal" submit_label = _("Start migration") success_url = reverse_lazy('horizon:admin:shares:index') submit_url = 'horizon:admin:shares:migration_start' cancel_url = reverse_lazy('horizon:admin:shares:index') page_title = _("Migrate a Share") def get_context_data(self, **kwargs): context = super(MigrationStartView, self).get_context_data(**kwargs) args = (self.kwargs['share_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] share = manila.share_get(self.request, share_id) except Exception: exceptions.handle( self.request, _('Unable to retrieve share details.'), redirect=self.success_url) return share def get_initial(self): share = self.get_data() return { 'share_id': self.kwargs["share_id"], 'name': share.name, } class MigrationCompleteView(forms.ModalFormView): form_class = project_forms.MigrationComplete template_name = 'admin/shares/migration_complete.html' modal_header = _("Confirm Migration Completion of Share") form_id = "migration_complete_share" modal_id = "migration_complete_share_modal" submit_label = _("Complete Migration") success_url = reverse_lazy('horizon:admin:shares:index') submit_url = 'horizon:admin:shares:migration_complete' cancel_url = reverse_lazy('horizon:admin:shares:index') page_title = _("Complete migration of a Share") def get_context_data(self, **kwargs): context = super(MigrationCompleteView, self).get_context_data(**kwargs) args = (self.kwargs['share_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] share = manila.share_get(self.request, share_id) except Exception: exceptions.handle( self.request, _('Unable to retrieve share details.'), redirect=self.success_url) return share def get_initial(self): share = self.get_data() return { 'share_id': self.kwargs["share_id"], 'name': share.name, } class MigrationCancelView(forms.ModalFormView): form_class = project_forms.MigrationCancel template_name = 'admin/shares/migration_cancel.html' modal_header = _("Confirm Migration Cancelling of Share") form_id = "migration_cancel_share" modal_id = "migration_cancel_share_modal" submit_label = _("Cancel Migration") success_url = reverse_lazy('horizon:admin:shares:index') submit_url = 'horizon:admin:shares:migration_cancel' cancel_url = reverse_lazy('horizon:admin:shares:index') page_title = _("Cancel migration of a Share") def get_context_data(self, **kwargs): context = super(MigrationCancelView, self).get_context_data(**kwargs) args = (self.kwargs['share_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] share = manila.share_get(self.request, share_id) except Exception: exceptions.handle( self.request, _('Unable to retrieve share details.'), redirect=self.success_url) return share def get_initial(self): share = self.get_data() return { 'share_id': self.kwargs["share_id"], 'name': share.name, } class MigrationGetProgressView(forms.ModalFormView): form_class = project_forms.MigrationGetProgress template_name = 'admin/shares/migration_get_progress.html' modal_header = _("Confirm Obtaining migration progress of Share") form_id = "migration_get_progress_share" modal_id = "migration_get_progress_share_modal" submit_label = _("Obtain Progress") success_url = reverse_lazy('horizon:admin:shares:index') submit_url = 'horizon:admin:shares:migration_get_progress' cancel_url = reverse_lazy('horizon:admin:shares:index') page_title = _("Obtain migration progress of a Share") def get_context_data(self, **kwargs): context = super(MigrationGetProgressView, self).get_context_data(**kwargs) args = (self.kwargs['share_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] share = manila.share_get(self.request, share_id) except Exception: exceptions.handle( self.request, _('Unable to retrieve share details.'), redirect=self.success_url) return share def get_initial(self): share = self.get_data() return { 'share_id': self.kwargs["share_id"], 'name': share.name, } class UnmanageShareView(forms.ModalFormView): form_class = project_forms.UnmanageShare form_id = "unmanage_share" template_name = 'admin/shares/unmanage_share.html' modal_header = _("Confirm Unmanage Share") modal_id = "unmanage_share_modal" submit_label = _("Unmanage") success_url = reverse_lazy('horizon:admin:shares:index') submit_url = 'horizon:admin:shares:unmanage' page_title = _("Unmanage Share") def get_context_data(self, **kwargs): context = super(UnmanageShareView, self).get_context_data(**kwargs) args = (self.kwargs['share_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] share = manila.share_get(self.request, share_id) except Exception: exceptions.handle( self.request, _('Unable to retrieve volume details.'), redirect=self.success_url) return share def get_initial(self): share = self.get_data() return { 'share_id': self.kwargs["share_id"], 'name': share.name, 'host': getattr(share, "host"), } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/0000775000175000017500000000000000000000000023475 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/__init__.py0000664000175000017500000000000000000000000025574 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/panel.py0000664000175000017500000000165000000000000025150 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.admin import dashboard class UserMessages(horizon.Panel): name = _("User Messages") slug = 'user_messages' permissions = ( 'openstack.services.share', ) dashboard.Admin.register(UserMessages) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/tables.py0000664000175000017500000000276400000000000025332 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tables from manila_ui.dashboards.project.user_messages import tables as project_tables class DeleteUserMessage(project_tables.DeleteUserMessage): pass class UserMessageIDColumn(project_tables.UserMessageIDColumn): pass class UserMessagesAdminTable(project_tables.UserMessagesTable): project_name = tables.Column( "project_name", verbose_name=_("Project"), ) class Meta(object): name = "user_messages" verbose_name = _("User Messages") table_actions = ( tables.NameFilterAction, DeleteUserMessage, ) row_actions = ( DeleteUserMessage, ) columns = ( 'project_name', 'message_id', 'message_level', 'resource_type', 'resource_id', 'user_message', 'created_at', ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/tabs.py0000664000175000017500000000157200000000000025005 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.dashboards.project.user_messages import tabs as project_tabs class UserMessagesOverviewTab(project_tabs.UserMessagesOverviewTab): template_name = "admin/user_messages/_detail.html" class UserMessagesDetailTabs(project_tabs.UserMessagesDetailTabs): pass ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7746513 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/templates/0000775000175000017500000000000000000000000025473 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/templates/user_messages/0000775000175000017500000000000000000000000030340 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/templates/user_messages/_detail.html0000664000175000017500000000156100000000000032632 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "User Messages Overview" %}


{% trans "ID" %}
{{ message.id }}
{% trans "Action" %}
{{ message.action_id }}
{% trans "Message" %}
{{ message.user_message }}
{% trans "Message Level" %}
{{ message.message_level }}
{% trans "Resource Type" %}
{{ message.resource_type }}
{% trans "Resource ID" %}
{{ message.resource_id }}
{% trans "Created at" %}
{{ message.created_at|parse_isotime }}
{% trans "Expires at" %}
{{ message.expires_at|parse_isotime }}
{% trans "Request ID" %}
{{ message.request_id }}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/templates/user_messages/detail.html0000664000175000017500000000034200000000000032467 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "User Messages Detail" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/templates/user_messages/index.html0000664000175000017500000000034500000000000032337 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "User Messages" %}{% endblock %} {% block main %}
{{ user_messages_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/urls.py0000664000175000017500000000170000000000000025032 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.admin.user_messages import views urlpatterns = [ re_path( r'^$', views.UserMessagesAdminView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.UserMessagesAdminDetailView.as_view(), name='user_messages_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/user_messages/views.py0000664000175000017500000000356000000000000025210 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.admin.user_messages import tables as admin_tables from manila_ui.dashboards.admin.user_messages import tabs as admin_tabs from manila_ui.dashboards.admin import utils from manila_ui.dashboards.project.user_messages import views as project_views class UserMessagesAdminView(project_views.UserMessagesView): table_classes = ( admin_tables.UserMessagesAdminTable, ) template_name = "admin/user_messages/index.html" @memoized.memoized_method def get_user_messages_data(self): try: messages = manila.messages_list(self.request) utils.set_project_name_to_objects(self.request, messages) except Exception: msg = _("Unable to retrieve messages list.") exceptions.handle(self.request, msg) return [] return messages class UserMessagesAdminDetailView(project_views.UserMessagesDetailView): tab_group_class = admin_tabs.UserMessagesDetailTabs template_name = 'admin/user_messages/detail.html' redirect_url = reverse_lazy('horizon:admin:user_messages:index') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/admin/utils.py0000664000175000017500000000307100000000000022343 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_utils import timeutils from django.utils.translation import gettext_lazy as _ from horizon import exceptions from openstack_dashboard.api import keystone PROJECTS = {} TIME = None def set_project_name_to_objects(request, objects): global PROJECTS, TIME try: # NOTE(vponomaryov): we will use saved values making lots of requests # in short period of time. 'memoized' is not suitable here now = timeutils.now() if TIME is None: TIME = now if not PROJECTS or now > TIME + 20: projects, has_more = keystone.tenant_list(request) PROJECTS = {t.id: t for t in projects} TIME = now except Exception: msg = _('Unable to retrieve list of projects.') exceptions.handle(request, msg) for obj in objects: project_id = getattr(obj, "project_id", None) project = PROJECTS.get(project_id, None) obj.project_name = getattr(project, "name", None) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/identity/0000775000175000017500000000000000000000000021371 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/identity/__init__.py0000664000175000017500000000000000000000000023470 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/identity/projects/0000775000175000017500000000000000000000000023222 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/identity/projects/__init__.py0000664000175000017500000000000000000000000025321 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/identity/projects/workflows.py0000664000175000017500000000562200000000000025636 0ustar00zuulzuul00000000000000# 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 django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import workflows from openstack_dashboard.api import base from openstack_dashboard.dashboards.identity.projects \ import workflows as project_workflows from manila_ui.api import manila as api_manila LOG = logging.getLogger(__name__) class ShareQuotaAction(project_workflows.CommonQuotaAction): shares = forms.IntegerField(min_value=-1, label=_("Shares")) share_gigabytes = forms.IntegerField( min_value=-1, label=_("Share gigabytes")) share_snapshots = forms.IntegerField( min_value=-1, label=_("Share snapshots")) share_snapshot_gigabytes = forms.IntegerField( min_value=-1, label=_("Share snapshot gigabytes")) share_networks = forms.IntegerField( min_value=-1, label=_("Share Networks")) share_groups = forms.IntegerField( min_value=-1, label=_("Share Groups")) share_group_snapshots = forms.IntegerField( min_value=-1, label=_("Share Group Snapshots")) _quota_fields = api_manila.MANILA_QUOTA_FIELDS def _tenant_quota_update(self, request, project_id, data): api_manila.tenant_quota_update(request, project_id, **data) class Meta(object): name = _("Share") slug = 'update_share_quotas' help_text = _("Set maximum quotas for the project.") permissions = ('openstack.roles.admin', 'openstack.services.share') class UpdateShareQuota(workflows.Step): action_class = ShareQuotaAction depends_on = ("project_id", "disabled_quotas") contributes = api_manila.MANILA_QUOTA_FIELDS def prepare_action_context(self, request, context): try: quotas = api_manila.tenant_quota_get( request, context['project_id']) for field in api_manila.MANILA_QUOTA_FIELDS: # Resolve mismatch UI field names and data field names. data_field = api_manila.MANILA_QUOTA_FIELDS_DATA_MAP[field] context[field] = quotas.get(data_field).limit except Exception as ex: LOG.exception(ex) exceptions.handle(request, _('Unable to retrieve share quotas.')) return context def allowed(self, request): return base.is_service_enabled(request, 'share') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8106513 manila-ui-11.0.0/manila_ui/dashboards/project/0000775000175000017500000000000000000000000021206 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/__init__.py0000664000175000017500000000134100000000000023316 0ustar00zuulzuul00000000000000# # 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. # Specify a custom application configuration. The comments in that class give # more background about why this is needed. default_app_config = 'manila_ui.dashboards.project.config.Config' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/config.py0000664000175000017500000000232200000000000023024 0ustar00zuulzuul00000000000000# # 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. # # Starting with Django 1.7, when a django app is loaded, it is assigned a # default label containing the portion of the application name after the last # period, and this name has to be globally unique. When horizon project # dashboard, openstack_dashboard.dashboards.project, is loaded, it is assigned # the label 'project'. But when the manila dashboard # manila_ui.dashboards.project is loaded, it label will conflict with # horizon's. Therefore this AppConfig class exists merely to specify a unique # configuration label and avoid this conflict. # from django import apps class Config(apps.AppConfig): name = 'manila_ui.dashboards.project' label = 'manila_project' ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8146515 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/0000775000175000017500000000000000000000000024760 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/__init__.py0000664000175000017500000000000000000000000027057 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/forms.py0000664000175000017500000001237500000000000026470 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. from django.forms import ValidationError from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.decorators.debug import sensitive_variables from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class Create(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Name")) dns_ip = forms.CharField(max_length="15", label=_("DNS IP")) ou = forms.CharField( max_length="255", label=_("Organizational Unit"), required=False) server = forms.CharField(max_length="255", label=_("Server")) domain = forms.CharField(max_length="255", label=_("Domain")) user = forms.CharField(max_length="255", label=_("User"), required=False) password = forms.CharField( label=_("Password"), widget=forms.PasswordInput(render_value=False), required=False) confirm_password = forms.CharField( label=_("Confirm Password"), widget=forms.PasswordInput(render_value=False), required=False) type = forms.ChoiceField(choices=(("", ""), ("active_directory", "Active Directory"), ("ldap", "LDAP"), ("kerberos", "Kerberos")), label=_("Type")) description = forms.CharField(widget=forms.Textarea, label=_("Description"), required=False) def clean(self): '''Check to make sure password fields match.''' data = super(forms.Form, self).clean() if 'password' in data: if data['password'] != data.get('confirm_password', None): raise ValidationError(_('Passwords do not match.')) return data @sensitive_variables('data') def handle(self, request, data): try: data.pop('confirm_password') security_service = manila.security_service_create( request, **data) messages.success(request, _('Successfully created security ' 'service: %s') % data['name']) return security_service except Exception: exceptions.handle(request, _('Unable to create security service.')) return False class Update(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Share Name")) dns_ip = forms.CharField( max_length="15", label=_("DNS IP"), required=False) ou = forms.CharField( max_length="255", label=_("Organizational Unit"), required=False) server = forms.CharField( max_length="255", label=_("Server"), required=False) domain = forms.CharField( max_length="255", label=_("Domain"), required=False) user = forms.CharField( max_length="255", label=_("User"), required=False) password = forms.CharField( label=_("Password"), widget=forms.PasswordInput(render_value=False), required=False) confirm_password = forms.CharField( label=_("Confirm Password"), widget=forms.PasswordInput(render_value=False), required=False) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def clean(self): '''Check to make sure password fields match.''' cleaned_data = super(forms.Form, self).clean() password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if password != confirm_password: raise ValidationError(_('Passwords do not match.')) return cleaned_data @sensitive_variables('data') def handle(self, request, data): sec_service_id = self.initial['sec_service_id'] try: manila.security_service_update( request, sec_service_id, dns_ip=data['dns_ip'], ou=data['ou'], server=data['server'], domain=data['domain'], password=data.get('password') or None, user=data['user'], name=data['name'], description=data['description']) message = _('Successfully updated security service ' '"%s"') % data['name'] messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:security_services:index") exceptions.handle(request, _('Unable to update security service.'), redirect=redirect) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/panel.py0000664000175000017500000000167100000000000026436 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class SecurityServices(horizon.Panel): name = _("Security Services") slug = 'security_services' permissions = ( 'openstack.services.share', ) dashboard.Project.register(SecurityServices) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/tables.py0000664000175000017500000000565000000000000026612 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import tables from manila_ui.api import manila class Create(tables.LinkAction): name = "create_security_service" verbose_name = _("Create Security Service") url = "horizon:project:security_services:security_service_create" classes = ("ajax-modal", "btn-create") icon = "plus" policy_rules = (("share", "security_service:create"),) class Delete(tables.DeleteAction): policy_rules = (("share", "security_service:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Security Service", u"Delete Security Services", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Security Service", u"Deleted Security Services", count ) def delete(self, request, obj_id): manila.security_service_delete(request, obj_id) class Edit(tables.LinkAction): name = "edit" verbose_name = _("Edit Security Service") url = "horizon:project:security_services:security_service_update" classes = ("ajax-modal", "btn-create") policy_rules = (("share", "security_service:update"),) class SecurityServicesTable(tables.DataTable): name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:project:security_services:security_service_detail") description = tables.Column("description", verbose_name=_("Description")) dns_ip = tables.Column("dns_ip", verbose_name=_("DNS IP")) ou = tables.Column("ou", verbose_name=_("Organizational Unit")) server = tables.Column("server", verbose_name=_("Server")) domain = tables.Column("domain", verbose_name=_("Domain")) user = tables.Column("user", verbose_name=_("User")) def get_object_display(self, security_service): return security_service.name or str(security_service.id) def get_object_id(self, security_service): return str(security_service.id) class Meta(object): name = "security_services" verbose_name = _("Security Services") table_actions = ( tables.NameFilterAction, Create, Delete) row_actions = ( Edit, Delete) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/tabs.py0000664000175000017500000000201300000000000026257 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class OverviewTab(tabs.Tab): name = _("Overview") slug = "overview" template_name = ("project/security_services/_detail.html") def get_context_data(self, request): return {"sec_service": self.tab_group.kwargs['sec_service']} class SecurityServiceDetailTabs(tabs.TabGroup): slug = "security_service_details" tabs = ( OverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/0000775000175000017500000000000000000000000026756 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8146515 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/0000775000175000017500000000000000000000000032530 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_add.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_add.htm0000664000175000017500000000335300000000000034135 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block form_id %}{% endblock %} {% block form_action %}{% url 'horizon:project:security_service:add_security_service' share_network.id %}{% endblock %} {% block modal_id %}add_security_service_modal{% endblock %} {% block modal-header %}{% trans "Add Security Service" %}{% endblock %} {% block modal-body %}
{% include "horizon/common/_form_fields.html" %}

{% trans "Description" %}:

{% blocktrans trimmed %} The security service can be used by backend drivers to configure clients, for more secure using of share. {% endblocktrans %}

{% include "horizon/common/_form_fields.html" %}
{{ step.get_help_text }}
{% endblock %} {% block modal-footer %} {% trans "Cancel" %} {% endblock %} ././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_create.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_create.0000664000175000017500000000047600000000000034142 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% blocktrans trimmed %} The security service can be used by backend drivers to configure clients, for more secure using of share. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_detail.0000664000175000017500000000214000000000000034127 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Security Service Overview" %}


{% trans "Type" %}
{{ sec_service.type }}
{% trans "Name" %}
{{ sec_service.name }}
{% trans "ID" %}
{{ sec_service.id }}
{% if sec_service.description %}
{% trans "Description" %}
{{ sec_service.description }}
{% endif %}
{% trans "Created at" %}
{{ sec_service.created_at|parse_date }}

{% trans "Security Service Details" %}


{% trans "DNS IP" %}
{{ sec_service.dns_ip }}
{% trans "Organizational Unit" %}
{{ sec_service.ou }}
{% trans "Server" %}
{{ sec_service.server }}
{% trans "Domain" %}
{{ sec_service.domain }}
{% trans "User" %}
{{ sec_service.user }}
././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_update.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/_update.0000664000175000017500000000036200000000000034153 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can modify name and description of a security service." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/add.html0000664000175000017500000000031000000000000034140 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Security Service" %}{% endblock %} {% block main %} {% include 'project/security_services/_add.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000020700000000000011454 xustar0000000000000000113 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/create.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/create.h0000664000175000017500000000031300000000000034141 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Security Service" %}{% endblock %} {% block main %} {% include 'project/security_services/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000020700000000000011454 xustar0000000000000000113 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/detail.h0000664000175000017500000000034600000000000034146 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Security Service Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/index.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/index.ht0000664000175000017500000000035500000000000034177 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Security Services" %}{% endblock %} {% block main %}
{{ security_services_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000020700000000000011454 xustar0000000000000000113 path=manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/update.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/templates/security_services/update.h0000664000175000017500000000031100000000000034156 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Edit Security Service" %}{% endblock %} {% block main %} {% include 'project/security_services/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/urls.py0000664000175000017500000000227400000000000026324 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.project.security_services import views urlpatterns = [ re_path( r'^$', views.SecurityServicesView.as_view(), name='index'), re_path( r'^create_security_service$', views.CreateView.as_view(), name='security_service_create'), re_path( r'^(?P[^/]+)/update/$', views.UpdateView.as_view(), name='security_service_update'), re_path( r'^(?P[^/]+)$', views.Detail.as_view(), name='security_service_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/security_services/views.py0000664000175000017500000001522200000000000026471 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.project.security_services import forms as ss_forms from manila_ui.dashboards.project.security_services import tables as ss_tables from manila_ui.dashboards.project.security_services import tabs as ss_tabs from manila_ui.dashboards.project.share_networks import forms as sn_forms from manila_ui.dashboards import utils class SecurityServicesView(tables.MultiTableView): table_classes = ( ss_tables.SecurityServicesTable, ) template_name = "project/security_services/index.html" page_title = _("Security Services") @memoized.memoized_method def get_security_services_data(self): try: security_services = manila.security_service_list(self.request) except Exception: security_services = [] exceptions.handle( self.request, _("Unable to retrieve security services")) return security_services class UpdateView(forms.ModalFormView): template_name = "project/security_services/update.html" form_class = ss_forms.Update form_id = "update_security_service" modal_header = _("Edit Security Service") modal_id = "update_security_service_modal" submit_label = _("Edit") submit_url = "horizon:project:security_services:security_service_update" success_url = reverse_lazy("horizon:project:security_services:index") page_title = _('Edit Security Service') def get_object(self): if not hasattr(self, "_object"): sec_service_id = self.kwargs['sec_service_id'] try: self._object = manila.security_service_get( self.request, sec_service_id) except Exception: msg = _('Unable to retrieve security_service.') url = reverse('horizon:project:security_services:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(UpdateView, self).get_context_data(**kwargs) args = (self.kwargs['sec_service_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): sec_service = self.get_object() return {'sec_service_id': self.kwargs["sec_service_id"], 'dns_ip': sec_service.dns_ip, 'ou': sec_service.ou, 'server': sec_service.server, 'domain': sec_service.domain, 'user': sec_service.user, 'name': sec_service.name, 'description': sec_service.description, } class CreateView(forms.ModalFormView): form_class = ss_forms.Create form_id = "create_security_service" template_name = 'project/security_services/create.html' modal_header = _("Create Security Service") modal_id = "create_security_service_modal" submit_label = _("Create") submit_url = reverse_lazy( "horizon:project:security_services:security_service_create") success_url = reverse_lazy("horizon:project:security_services:index") page_title = _('Create Security Service') class AddSecurityServiceView(forms.ModalFormView): form_class = sn_forms.AddSecurityServiceForm template_name = 'project/security_services/add.html' success_url = 'horizon:project:security_services:index' page_title = _('Add Security Service') def get_object(self): if not hasattr(self, "_object"): share_id = self.kwargs['share_network_id'] try: self._object = manila.share_network_get(self.request, share_id) except Exception: msg = _('Unable to retrieve share network.') url = reverse('horizon:project:security_services:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(AddSecurityServiceView, self).get_context_data(**kwargs) context['share_network'] = self.get_object() return context def get_initial(self): share_net = self.get_object() return {'share_net_id': self.kwargs["share_network_id"], 'name': share_net.name, 'description': share_net.description} class Detail(tabs.TabView): tab_group_class = ss_tabs.SecurityServiceDetailTabs template_name = 'project/security_services/detail.html' redirect_url = reverse_lazy('horizon:project:security_services:index') def get_context_data(self, **kwargs): context = super(Detail, self).get_context_data(**kwargs) sec_service = self.get_data() context["sec_service"] = sec_service sec_service_display_name = sec_service.name or sec_service.id context["sec_service_display_name"] = sec_service_display_name context["page_title"] = _("Security Service Details: " "%(service_display_name)s") % \ {'service_display_name': sec_service_display_name} return context @memoized.memoized_method def get_data(self): try: sec_service_id = self.kwargs['sec_service_id'] sec_service = manila.security_service_get( self.request, sec_service_id) sec_service.type = utils.get_nice_security_service_type( sec_service) except Exception: message = _("Unable to retrieve security service " "'%s' details.") % sec_service_id exceptions.handle( self.request, message, redirect=self.redirect_url) return sec_service def get_tabs(self, request, *args, **kwargs): sec_service = self.get_data() return self.tab_group_class(request, sec_service=sec_service, **kwargs) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8146515 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/0000775000175000017500000000000000000000000025626 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/__init__.py0000664000175000017500000000000000000000000027725 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/forms.py0000664000175000017500000000560200000000000027331 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class CreateShareGroupSnapshotForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Name"), required=True) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def __init__(self, request, *args, **kwargs): super(self.__class__, self).__init__(request, *args, **kwargs) # populate share_group_id sg_id = kwargs.get('initial', {}).get('share_group_id', []) self.fields['share_group_id'] = forms.CharField( widget=forms.HiddenInput(), initial=sg_id) def handle(self, request, data): try: snapshot = manila.share_group_snapshot_create( request, data['share_group_id'], data['name'], data['description']) message = _('Creating share group snapshot "%s".') % data['name'] messages.success(request, message) return snapshot except Exception: redirect = reverse("horizon:project:share_group_snapshots:index") exceptions.handle( request, _('Unable to create share group snapshot.'), redirect=redirect) return False class UpdateShareGroupSnapshotForm(forms.SelfHandlingForm): name = forms.CharField( max_length="255", label=_("Name")) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def handle(self, request, data): sgs_id = self.initial['share_group_snapshot_id'] try: manila.share_group_snapshot_update( request, sgs_id, data['name'], data['description']) message = _('Updating share group snapshot "%s"') % data['name'] messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:share_group_snapshots:index") exceptions.handle( request, _('Unable to update share group snapshot.'), redirect=redirect) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/panel.py0000664000175000017500000000173600000000000027306 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class ShareGroupSnapshots(horizon.Panel): name = _("Share Group Snapshots") slug = 'share_group_snapshots' permissions = ( 'openstack.services.share', ) dashboard.Project.register(ShareGroupSnapshots) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/tables.py0000664000175000017500000001311400000000000027452 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.template.defaultfilters import title from django.urls import reverse from django.utils.http import urlencode from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import exceptions from horizon import tables from horizon.utils import filters from manila_ui.api import manila class UpdateShareGroupSnapshot(tables.LinkAction): name = "update_share_group_snapshot" verbose_name = _("Update") url = "horizon:project:share_group_snapshots:update" classes = ("ajax-modal", "btn-camera") def allowed(self, request, share_group_snapshot=None): return share_group_snapshot.status in ("available", "error") class CreateShareGroupSnapshot(tables.LinkAction): name = "create_share_group_snapshot" verbose_name = _("Create Share Group Snapshot") url = "horizon:project:share_group_snapshots:create" classes = ("ajax-modal", "btn-camera") def allowed(self, request, share_group=None): self.verbose_name = _("Create Share Group Snapshot") classes = [c for c in self.classes if c != "disabled"] self.classes = classes return share_group.status == "available" class CreateShareGroupFromSnapshot(tables.LinkAction): name = "create_share_group_from_snapshot" verbose_name = _("Create Share Group") url = "horizon:project:share_groups:create" classes = ("ajax-modal", "btn-camera") def get_link_url(self, datum): base_url = reverse(self.url) params = urlencode({ "snapshot_id": self.table.get_object_id(datum)}) return "?".join([base_url, params]) def allowed(self, request, share_group=None): return share_group.status == "available" class ShareGroupSnapshotShareGroupNameColumn(tables.Column): def get_link_url(self, snapshot): return reverse(self.link, args=(snapshot.share_group_id,)) class DeleteShareGroupSnapshot(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Group Snapshot", u"Delete Share Group Snapshots", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Group Snapshot", u"Deleted Share Group Snapshots", count ) def delete(self, request, obj_id): obj = self.table.get_object_by_id(obj_id) name = self.table.get_object_display(obj) try: manila.share_group_snapshot_delete(request, obj_id) except Exception: msg = _('Unable to delete share group snapshot "%s". ' 'One or more share groups depend on it.') exceptions.handle(self.request, msg % name) raise def allowed(self, request, snapshot=None): if snapshot: return snapshot.status.lower() in ('available', 'error') return True class UpdateShareGroupSnapshotRow(tables.Row): ajax = True def get_data(self, request, share_group_snapshot_id): snapshot = manila.share_group_snapshot_get( request, share_group_snapshot_id) if not snapshot.name: snapshot.name = share_group_snapshot_id return snapshot class ShareGroupSnapshotsTable(tables.DataTable): STATUS_CHOICES = ( ("available", True), ("creating", None), ("error", False), ) STATUS_DISPLAY_CHOICES = ( ("available", pgettext_lazy("Current status of snapshot", u"Available")), ("creating", pgettext_lazy("Current status of snapshot", u"Creating")), ("error", pgettext_lazy("Current status of snapshot", u"Error")), ) name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:project:share_group_snapshots:detail") description = tables.Column( "description", verbose_name=_("Description"), truncate=40) created_at = tables.Column( "created_at", verbose_name=_("Created at"), filters=( filters.parse_isotime, )) status = tables.Column( "status", filters=(title,), verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) source = ShareGroupSnapshotShareGroupNameColumn( "share_group", verbose_name=_("Source"), link="horizon:project:share_groups:detail") def get_object_display(self, obj): return obj.name class Meta(object): name = "share_group_snapshots" verbose_name = _("Share Group Snapshots") status_columns = ["status"] row_class = UpdateShareGroupSnapshotRow table_actions = ( tables.NameFilterAction, DeleteShareGroupSnapshot, ) row_actions = ( CreateShareGroupFromSnapshot, UpdateShareGroupSnapshot, DeleteShareGroupSnapshot, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/tabs.py0000664000175000017500000000227400000000000027136 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareGroupSnapshotOverviewTab(tabs.Tab): name = _("Share Group Snapshot Overview") slug = "share_group_snapshot_overview_tab" template_name = "project/share_group_snapshots/_detail.html" def get_context_data(self, request): return {"share_group_snapshot": self.tab_group.kwargs[ "share_group_snapshot"]} class ShareGroupSnapshotDetailTabs(tabs.TabGroup): slug = "share_group_snapshot_details" tabs = ( ShareGroupSnapshotOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/0000775000175000017500000000000000000000000027624 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8146515 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000775000175000017500000000000000000000000034244 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000022000000000000011447 xustar0000000000000000122 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/_create.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000040000000000000034240 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}
Please, choose a name for the new share group snapshot, that will be created from '{{ share_group_name }}' share group.
{% endblock %} ././@PaxHeader0000000000000000000000000000022000000000000011447 xustar0000000000000000122 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/_detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000160300000000000034246 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Group Snapshot Overview" %}


{% trans "Name" %}
{{ share_group_snapshot.name }}
{% trans "ID" %}
{{ share_group_snapshot.id }}
{% url 'horizon:project:share_groups:detail' share_group_snapshot.share_group_id as sg_url %}
{% trans "Source Share Group" %}
{{ share_group_snapshot.sg_name_or_id }}
{% if share_group_snapshot.description %}
{% trans "Description" %}
{{ share_group_snapshot.description }}
{% endif %}
{% trans "Status" %}
{{ share_group_snapshot.status|capfirst }}
{% trans "Created" %}
{{ share_group_snapshot.created_at|parse_date }}
././@PaxHeader0000000000000000000000000000022000000000000011447 xustar0000000000000000122 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/_update.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000036200000000000034247 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can modify name and description of a share group snapshot." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/create.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000032300000000000034244 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share Group Snapshot" %}{% endblock %} {% block main %} {% include 'project/share_group_snapshots/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/detail.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000035200000000000034246 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Snapshot Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000021600000000000011454 xustar0000000000000000120 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/index.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000036500000000000034252 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Snapshots" %}{% endblock %} {% block main %}
{{ share_group_snapshots_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/update.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/0000664000175000017500000000032300000000000034244 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Update Share Group Snapshot" %}{% endblock %} {% block main %} {% include 'project/share_group_snapshots/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/urls.py0000664000175000017500000000257400000000000027175 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.urls import re_path from manila_ui.dashboards.project.share_group_snapshots import views from manila_ui import features if features.is_share_groups_enabled(): urlpatterns = [ re_path( r'^$', views.ShareGroupSnapshotsView.as_view(), name='index'), re_path( r'^(?P[^/]+)/snapshot_create/$', views.CreateShareGroupSnapshotView.as_view(), name='create'), re_path( r'^(?P[^/]+)/$', views.ShareGroupSnapshotDetailView.as_view(), name='detail'), re_path( r'^(?P[^/]+)/update/$', views.UpdateShareGroupSnapshotView.as_view(), name='update'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_group_snapshots/views.py0000664000175000017500000001525200000000000027342 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. """ Project views for managing share group snapshots. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila import manila_ui.dashboards.project.share_group_snapshots.forms as sgs_forms import manila_ui.dashboards.project.share_group_snapshots.tables as sgs_tables import manila_ui.dashboards.project.share_group_snapshots.tabs as sgs_tabs class ShareGroupSnapshotsView(tables.MultiTableView): table_classes = ( sgs_tables.ShareGroupSnapshotsTable, ) template_name = "project/share_group_snapshots/index.html" page_title = _("Share Group Snapshots") @memoized.memoized_method def get_share_group_snapshots_data(self): share_group_snapshots = [] try: share_group_snapshots = manila.share_group_snapshot_list( self.request, search_opts={'all_tenants': True}) share_groups = manila.share_group_list(self.request) sg_names = dict([(sg.id, sg.name or sg.id) for sg in share_groups]) for snapshot in share_group_snapshots: snapshot.share_group = sg_names.get(snapshot.share_group_id) except Exception: msg = _("Unable to retrieve share group snapshot list.") exceptions.handle(self.request, msg) return share_group_snapshots class ShareGroupSnapshotDetailView(tabs.TabView): tab_group_class = sgs_tabs.ShareGroupSnapshotDetailTabs template_name = "project/share_group_snapshots/detail.html" redirect_url = reverse_lazy("horizon:project:share_group_snapshots:index") def get_context_data(self, **kwargs): context = super(ShareGroupSnapshotDetailView, self).get_context_data( **kwargs) snapshot = self.get_data() snapshot_display_name = snapshot.name or snapshot.id context["snapshot"] = snapshot context["snapshot_display_name"] = snapshot_display_name context["page_title"] = _( "Share Group Snapshot Details: %(sgs_display_name)s") % ( {'sgs_display_name': snapshot_display_name}) return context @memoized.memoized_method def get_data(self): try: share_group_snapshot = manila.share_group_snapshot_get( self.request, self.kwargs['share_group_snapshot_id']) sg = manila.share_group_get( self.request, share_group_snapshot.share_group_id) share_group_snapshot.sg_name_or_id = sg.name or sg.id except Exception: exceptions.handle( self.request, _('Unable to retrieve share group snapshot details.'), redirect=self.redirect_url) return share_group_snapshot def get_tabs(self, request, *args, **kwargs): return self.tab_group_class( request, share_group_snapshot=self.get_data(), **kwargs) class CreateShareGroupSnapshotView(forms.ModalFormView): form_class = sgs_forms.CreateShareGroupSnapshotForm form_id = "create_share_group_snapshot" template_name = 'project/share_group_snapshots/create.html' modal_header = _("Create Share Group Snapshot") modal_id = "create_share_group_snapshot_modal" submit_label = _("Create Share Group Snapshot") submit_url = "horizon:project:share_group_snapshots:create" success_url = reverse_lazy('horizon:project:share_group_snapshots:index') page_title = _('Create Share Group Snapshot') def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) sg_id = self.kwargs['share_group_id'] try: sg = manila.share_group_get(self.request, sg_id) context['share_group_name'] = sg.name or sg_id except Exception: exceptions.handle( self.request, _("Unable to get the specified share group '%s' for " "snapshot creation.") % sg_id) context['share_group_name'] = sg_id context['share_group_id'] = sg_id # TODO(vponomaryov): add support of quotas when it is implemented # for share group snapshots on server side. # https://bugs.launchpad.net/manila/+bug/1868644 return context def get_initial(self): self.submit_url = reverse(self.submit_url, kwargs=self.kwargs) return {'share_group_id': self.kwargs["share_group_id"]} class UpdateShareGroupSnapshotView(forms.ModalFormView): form_class = sgs_forms.UpdateShareGroupSnapshotForm form_id = "update_share_group_snapshot" template_name = 'project/share_group_snapshots/update.html' modal_header = _("Update Share Group Snapshot") modal_id = "update_share_group_snapshot_modal" submit_label = _("Update") submit_url = "horizon:project:share_group_snapshots:update" success_url = reverse_lazy('horizon:project:share_group_snapshots:index') page_title = _('Update Share Group') @memoized.memoized_method def get_object(self): if not hasattr(self, "_object"): try: self._object = manila.share_group_snapshot_get( self.request, self.kwargs['share_group_snapshot_id']) except Exception: msg = _('Unable to retrieve share group snapshot.') url = reverse('horizon:project:share_group_snapshots:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): snapshot = self.get_object() return { 'share_group_snapshot_id': self.kwargs["share_group_snapshot_id"], 'name': snapshot.name, 'description': snapshot.description, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8186514 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/0000775000175000017500000000000000000000000023707 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/__init__.py0000664000175000017500000000000000000000000026006 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/forms.py0000664000175000017500000002632100000000000025413 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.forms import ValidationError from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards import utils class CreateShareGroupForm(forms.SelfHandlingForm): name = forms.CharField(label=_("Name"), max_length="255", required=True) description = forms.CharField( label=_("Description"), max_length="255", widget=forms.Textarea(attrs={"rows": 3}), required=False) def __init__(self, request, *args, **kwargs): super(CreateShareGroupForm, self).__init__(request, *args, **kwargs) self.st_field_name_prefix = "share-type-choices-" self.fields["source_type"] = forms.ChoiceField( label=_("Source Type"), widget=forms.Select(attrs={ "class": "switchable", "data-slug": "source", }), required=False) self.fields["snapshot"] = forms.ChoiceField( label=_("Use share group snapshot as a source"), widget=forms.SelectWidget(attrs={ "class": "switched", "data-switch-on": "source", "data-source-snapshot": _("Share Group Snapshot"), }), required=True) if ("snapshot_id" in request.GET or kwargs.get("data", {}).get("snapshot")): try: snapshot = self.get_share_group_snapshot( request, request.GET.get( "snapshot_id", kwargs.get("data", {}).get("snapshot"))) self.fields["name"].initial = snapshot.name self.fields["snapshot"].choices = ( (snapshot.id, snapshot.name or snapshot.id), ) try: # Set the share group type from the original share group orig_sg = manila.share_group_get( request, snapshot.share_group_id) self.fields["sgt"].initial = orig_sg.share_group_type_id except Exception: pass del self.fields["source_type"] except Exception: exceptions.handle( request, _("Unable to load the specified share group snapshot.")) else: source_type_choices = [] try: snapshot_list = manila.share_group_snapshot_list(request) snapshots = [s for s in snapshot_list if s.status == "available"] if snapshots: source_type_choices.append(("snapshot", _("Snapshot"))) self.fields["snapshot"].choices = ( [("", _("Choose a snapshot"))] + [(s.id, s.name or s.id) for s in snapshots] ) else: del self.fields["snapshot"] except Exception: exceptions.handle( request, _("Unable to retrieve share group snapshots.")) if source_type_choices: choices = ([('none', _("No source, empty share group"))] + source_type_choices) self.fields["source_type"].choices = choices else: del self.fields["source_type"] self.fields["az"] = forms.ChoiceField( label=_("Availability Zone"), widget=forms.SelectWidget(attrs={ "class": "switched", "data-switch-on": "source", "data-source-none": _("Availability Zone"), }), required=False) availability_zones = manila.availability_zone_list(request) self.fields["az"].choices = ( [("", "")] + [(az.name, az.name) for az in availability_zones]) share_group_types = manila.share_group_type_list(request) self.fields["sgt"] = forms.ChoiceField( label=_("Share Group Type"), widget=forms.fields.SelectWidget(attrs={ "class": "switched switchable", "data-switch-on": "source", "data-source-none": _("Share Group Type"), "data-slug": "sgt", }), required=True) self.fields["sgt"].choices = ( [(utils.transform_dashed_name(sgt.id), sgt.name) for sgt in share_group_types] ) # NOTE(vponomaryov): create separate set of available share types # for each of share group types. share_types = manila.share_type_list(request) for sgt in share_group_types: st_choices = ( [(st.id, st.name) for st in share_types if st.id in sgt.share_types]) amount_of_choices = len(st_choices) st_field_name = ( self.st_field_name_prefix + utils.transform_dashed_name(sgt.id) ) if amount_of_choices < 2: st_field = forms.ChoiceField( label=_("Share Types"), choices=st_choices, widget=forms.fields.SelectWidget(attrs={ "class": "switched", "data-switch-on": "sgt", "data-sgt-%s" % utils.transform_dashed_name( sgt.id): _("Share Types (one available)"), }), required=True) else: height = min(30 * amount_of_choices, 155) st_field = forms.MultipleChoiceField( label=_("Share Types"), choices=st_choices, widget=forms.fields.widgets.SelectMultiple(attrs={ "style": "max-height: %spx;" % height, "class": "switched", "data-switch-on": "sgt", "data-sgt-%s" % utils.transform_dashed_name( sgt.id): _("Share Types (multiple available)"), }), required=False) st_field.initial = st_choices[0] self.fields[st_field_name] = st_field self.fields["share_network"] = forms.ChoiceField( label=_("Share Network"), widget=forms.fields.SelectWidget(attrs={ "class": "switched", "data-switch-on": "source", "data-source-none": _("Share Network"), }), required=False) share_networks = manila.share_network_list(request) self.fields["share_network"].choices = ( [(sn.id, sn.name or sn.id) for sn in share_networks]) def clean(self): cleaned_data = super(CreateShareGroupForm, self).clean() form_errors = list(self.errors) for error in form_errors: sgt_name = error.split(self.st_field_name_prefix)[-1] chosen_sgt = cleaned_data.get("sgt") if (error.startswith(self.st_field_name_prefix) and sgt_name != chosen_sgt): cleaned_data[error] = "Not set" self.errors.pop(error, None) source_type = cleaned_data.get("source_type") if source_type != "snapshot": self.errors.pop("snapshot", None) share_group_type = cleaned_data.get("sgt") if share_group_type: cleaned_data["share_types"] = cleaned_data.get( self.st_field_name_prefix + share_group_type) if isinstance(cleaned_data["share_types"], str): cleaned_data["share_types"] = [cleaned_data["share_types"]] else: self.errors.pop("sgt", None) return cleaned_data def handle(self, request, data): try: source_type = data.get('source_type') if (data.get("snapshot") and source_type in (None, 'snapshot')): snapshot = self.get_share_group_snapshot( request, data["snapshot"]) snapshot_id = snapshot.id source_sg = manila.share_group_get( request, snapshot.share_group_id) data['sgt'] = source_sg.share_group_type_id else: snapshot_id = None share_group = manila.share_group_create( request, name=data['name'], description=data['description'], share_group_type=utils.transform_dashed_name(data['sgt']), share_types=None if snapshot_id else data.get('share_types'), share_network=( None if snapshot_id else data.get('share_network')), source_share_group_snapshot=snapshot_id, availability_zone=None if snapshot_id else data['az']) message = _('Creating share group "%s"') % data['name'] messages.success(request, message) return share_group except ValidationError as e: self.api_error(e.messages[0]) return False except Exception: exceptions.handle(request, ignore=True) self.api_error(_("Unable to create share group.")) return False @memoized.memoized def get_share_group_snapshot(self, request, sg_snapshot_id): return manila.share_group_snapshot_get(request, sg_snapshot_id) class UpdateShareGroupForm(forms.SelfHandlingForm): name = forms.CharField( max_length="255", label=_("Share Group Name")) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def handle(self, request, data): sg_id = self.initial['share_group_id'] try: manila.share_group_update( request, sg_id, data['name'], data['description']) message = _('Updating share group "%s"') % data['name'] messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:share_groups:index") exceptions.handle( request, _('Unable to update share group.'), redirect=redirect) return False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/panel.py0000664000175000017500000000167400000000000025370 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class ShareGroups(horizon.Panel): name = _("Share Groups") slug = 'share_groups' permissions = ( 'openstack.services.share', ) dashboard.Project.register(ShareGroups) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/tables.py0000664000175000017500000001166700000000000025546 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import tables from manila_ui.api import manila import manila_ui.dashboards.project.share_group_snapshots.tables as sgs_tables class UpdateShareGroup(tables.LinkAction): name = "update" verbose_name = _("Update") url = "horizon:project:share_groups:update" classes = ("ajax-modal", "btn-create") def allowed(self, request, share_group=None): return share_group.status in ("available", "error") class DeleteShareGroup(tables.DeleteAction): @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Group", u"Delete Share Groups", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Group", u"Deleted Share Groups", count ) def delete(self, request, obj_id): manila.share_group_delete(request, obj_id) def allowed(self, request, share_group=None): if share_group: # Row button return (share_group.status.lower() in ('available', 'error')) # Table button. Always return 'True' return True class CreateShareGroup(tables.LinkAction): name = "create" verbose_name = _("Create Share Group") url = "horizon:project:share_groups:create" classes = ("ajax-modal", "btn-create") icon = "plus" policy_rules = (("share", "share_group:create"),) def allowed(self, request, share=None): # TODO(vponomaryov): implement quota restriction when quota support # is implemented for share groups. # https://bugs.launchpad.net/manila/+bug/1868644 return True class UpdateShareGroupRow(tables.Row): ajax = True def get_data(self, request, sg_id): sg = manila.share_group_get(request, sg_id) return sg class ShareGroupsTable(tables.DataTable): def get_share_network_link(share_group): if getattr(share_group, 'share_network_id', None): return reverse( "horizon:project:share_networks:share_network_detail", args=(share_group.share_network_id,)) else: return None def get_source_share_group_snapshot_link(share_group): if getattr(share_group, 'source_share_group_snapshot_id', None): return reverse( "horizon:project:share_group_snapshots:detail", args=(share_group.source_share_group_snapshot_id,)) else: return None STATUS_CHOICES = ( ("available", True), ("creating", None), ("deleting", None), ("error", False), ("error_deleting", False), ) STATUS_DISPLAY_CHOICES = ( ("available", u"Available"), ("creating", u"Creating"), ("deleting", u"Deleting"), ("error", u"Error"), ("error_deleting", u"Error deleting"), ) name = tables.Column( "name", verbose_name=_("Name"), link="horizon:project:share_groups:detail") status = tables.Column( "status", verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES, ) availability_zone = tables.Column( "availability_zone", verbose_name=_("Availability Zone")) share_network_id = tables.Column( "share_network_id", verbose_name=_("Share Network"), link=get_share_network_link) source_share_group_snapshot_id = tables.Column( "source_share_group_snapshot_id", verbose_name=_("Source Share Group Snapshot"), link=get_source_share_group_snapshot_link) def get_object_display(self, share_group): return str(share_group.id) def get_object_id(self, share_group): return str(share_group.id) class Meta(object): name = "share_groups" verbose_name = _("Share Groups") status_columns = ("status", ) row_class = UpdateShareGroupRow table_actions = ( CreateShareGroup, tables.NameFilterAction, DeleteShareGroup, ) row_actions = ( sgs_tables.CreateShareGroupSnapshot, UpdateShareGroup, DeleteShareGroup, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/tabs.py0000664000175000017500000000214100000000000025210 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareGroupOverviewTab(tabs.Tab): name = _("Share Group Overview") slug = "share_group_overview_tab" template_name = "project/share_groups/_detail.html" def get_context_data(self, request): return {"share_group": self.tab_group.kwargs["share_group"]} class ShareGroupDetailTabs(tabs.TabGroup): slug = "share_group_details" tabs = ( ShareGroupOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/0000775000175000017500000000000000000000000025705 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8186514 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/0000775000175000017500000000000000000000000030406 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/_create.html0000664000175000017500000000033300000000000032675 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "Select parameters of share group you want to create. " %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/_detail.html0000664000175000017500000000562000000000000032700 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Group Overview" %}


{% trans "ID" %}
{{ share_group.id }}
{% trans "Name" %}
{{ share_group.name }}
{% trans "Description" %}
{{ share_group.description }}
{% trans "Status" %}
{{ share_group.status|capfirst }}
{% trans "Created" %}
{{ share_group.created_at|parse_date }}
{% if share_group.source_share_group_snapshot_id %}
{% trans "Source SG Snapshot" %}
{% url 'horizon:project:share_group_snapshots:detail' share_group.source_share_group_snapshot_id as ssgs_url%}
{{ share_group.source_share_group_snapshot_id }}
{% endif %}
{% trans "Capabilities" %}
{% if share_group.consistent_snapshot_support %} Consistent snapshots are supported {% else %} None {% endif %}
{% if share_group.availability_zone %}
{% trans "Availability Zone" %}
{{ share_group.availability_zone }}
{% endif %} {% if share_group.share_network_id %}
{% trans "Share Network" %}
{% url 'horizon:project:share_networks:share_network_detail' share_group.share_network_id as sn_url%}
{{ share_group.share_network_id }}
{% endif %} {% if share_group.share_group_type %}
{% trans "Share Group Type" %}
{% trans "Share Group Type Name:" %} {{ share_group.share_group_type.name }}
{% trans "Share Group Type ID:" %} {{ share_group.share_group_type.id }}
{% trans "Share Group Type Specs:" %} {{ share_group.share_group_type.group_specs }}

{% endif %} {% if share_group.share_types %}
{% trans "Share Types" %}
{% for st in share_group.share_types %}
{% trans "Share Type Name:" %} {{ st.name }}
{% trans "Share Type Visibility:" %} {% if st.is_public %}Public{% else %}Private{% endif %}
{% trans "Network handling enabled:" %} {{ st.dhss }}

{% endfor %} {% endif %} {% if share_group.members %}
{% trans "Shares" %}
{% for m in share_group.members %} {% url 'horizon:project:shares:detail' m.id as share_url%}
{% endfor %} {% endif %}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/_update.html0000664000175000017500000000037100000000000032716 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can modify name, description and visibility of a share group." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/create.html0000664000175000017500000000030100000000000032531 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share Group" %}{% endblock %} {% block main %} {% include 'project/share_groups/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/detail.html0000664000175000017500000000034100000000000032534 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Group Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/index.html0000664000175000017500000000034300000000000032403 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Groups" %}{% endblock %} {% block main %}
{{ share_groups_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/templates/share_groups/update.html0000664000175000017500000000030100000000000032550 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Update Share Group" %}{% endblock %} {% block main %} {% include 'project/share_groups/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/urls.py0000664000175000017500000000243500000000000025252 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # 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. from django.urls import re_path from manila_ui.dashboards.project.share_groups import views from manila_ui import features if features.is_share_groups_enabled(): urlpatterns = [ re_path( r'^$', views.ShareGroupsView.as_view(), name='index'), re_path( r'^create/$', views.ShareGroupCreateView.as_view(), name='create'), re_path( r'^(?P[^/]+)/$', views.ShareGroupDetailView.as_view(), name='detail'), re_path( r'^(?P[^/]+)/update/$', views.ShareGroupUpdateView.as_view(), name='update'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_groups/views.py0000664000175000017500000001332000000000000025415 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # 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. """ Project views for managing share groups. """ from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.project.share_groups import forms as sg_forms from manila_ui.dashboards.project.share_groups import tables as sg_tables from manila_ui.dashboards.project.share_groups import tabs as sg_tabs class ShareGroupsView(tables.MultiTableView): table_classes = ( sg_tables.ShareGroupsTable, ) template_name = "project/share_groups/index.html" page_title = _("Share Groups") @memoized.memoized_method def get_share_groups_data(self): try: share_groups = manila.share_group_list( self.request, detailed=True) except Exception: share_groups = [] exceptions.handle( self.request, _("Unable to retrieve share groups.")) return share_groups class ShareGroupDetailView(tabs.TabView): tab_group_class = sg_tabs.ShareGroupDetailTabs template_name = 'project/share_groups/detail.html' def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) share_group = self.get_data() context["share_group"] = share_group context["page_title"] = ( _("Share Group Details: %s") % share_group.id) return context @memoized.memoized_method def get_data(self): try: share_group_id = self.kwargs['share_group_id'] share_group = manila.share_group_get(self.request, share_group_id) members = manila.share_list( self.request, search_opts={"share_group_id": share_group_id}) share_group.members = members share_types = manila.share_type_list(self.request) share_group.share_group_type = manila.share_group_type_get( self.request, share_group.share_group_type_id) share_group.share_types = [ {"id": st.id, "name": st.name, "is_public": getattr(st, 'share_type_access:is_public'), "dhss": st.extra_specs.get('driver_handles_share_servers')} for st in share_types if st.id in share_group.share_types ] return share_group except Exception: redirect = reverse('horizon:project:share_groups:index') exceptions.handle( self.request, _('Unable to retrieve share group details.'), redirect=redirect) def get_tabs(self, request, *args, **kwargs): share_group = self.get_data() return self.tab_group_class(request, share_group=share_group, **kwargs) class ShareGroupCreateView(forms.ModalFormView): form_class = sg_forms.CreateShareGroupForm form_id = "create_share_group" template_name = 'project/share_groups/create.html' modal_header = _("Create Share Group") modal_id = "create_share_group_modal" submit_label = _("Create") submit_url = reverse_lazy("horizon:project:share_groups:create") success_url = reverse_lazy("horizon:project:share_groups:index") page_title = _('Create a Share') def get_context_data(self, **kwargs): context = super(ShareGroupCreateView, self).get_context_data(**kwargs) try: # TODO(vponomaryov): add quota logic here when quotas are # implemented for share groups. # https://bugs.launchpad.net/manila/+bug/1868644 pass except Exception: exceptions.handle(self.request) return context class ShareGroupUpdateView(forms.ModalFormView): form_class = sg_forms.UpdateShareGroupForm form_id = "update_share_group" template_name = 'project/share_groups/update.html' modal_header = _("Update") modal_id = "update_share_group_modal" submit_label = _("Update") submit_url = "horizon:project:share_groups:update" success_url = reverse_lazy("horizon:project:share_groups:index") page_title = _("Update Share Group") def get_object(self): if not hasattr(self, "_object"): sg_id = self.kwargs['share_group_id'] try: self._object = manila.share_group_get(self.request, sg_id) except Exception: msg = _('Unable to retrieve share group.') url = reverse('horizon:project:share_groups:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(ShareGroupUpdateView, self).get_context_data(**kwargs) return context def get_initial(self): self.submit_url = reverse(self.submit_url, kwargs=self.kwargs) sg = self.get_object() return { 'share_group_id': self.kwargs["share_group_id"], 'name': sg.name, 'description': sg.description, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8186514 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/0000775000175000017500000000000000000000000024244 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/__init__.py0000664000175000017500000000000000000000000026343 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/forms.py0000664000175000017500000001300500000000000025743 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from openstack_dashboard.api import base from openstack_dashboard.api import neutron from manila_ui.api import manila from manila_ui.dashboards import utils class Create(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Name")) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def __init__(self, request, *args, **kwargs): super(Create, self).__init__(request, *args, **kwargs) self.neutron_enabled = base.is_service_enabled(request, 'network') if self.neutron_enabled: net_choices = neutron.network_list(request) self.fields['neutron_net_id'] = forms.ChoiceField( choices=[(' ', ' ')] + [(utils.transform_dashed_name(choice.id), choice.name_or_id) for choice in net_choices], label=_("Neutron Net"), widget=forms.Select( attrs={'class': 'switchable', 'data-slug': 'net'})) for net in net_choices: # For each network create switched choice field with # the its subnet choices subnet_field_name = ( 'subnet-choices-%s' % utils.transform_dashed_name(net.id) ) subnet_field = forms.ChoiceField( choices=(), label=_("Neutron Subnet"), widget=forms.Select(attrs={ 'class': 'switched', 'data-switch-on': 'net', 'data-net-%s' % utils.transform_dashed_name(net.id): _("Neutron Subnet") })) self.fields[subnet_field_name] = subnet_field subnet_choices = neutron.subnet_list( request, network_id=net.id) self.fields[subnet_field_name].choices = [ (' ', ' ')] + [(choice.id, choice.name_or_id) for choice in subnet_choices] def handle(self, request, data): try: send_data = {'name': data['name']} if data['description']: send_data['description'] = data['description'] neutron_net_id = data.get('neutron_net_id') if self.neutron_enabled and neutron_net_id: send_data['neutron_net_id'] = utils.transform_dashed_name( neutron_net_id.strip()) subnet_key = 'subnet-choices-%s' % neutron_net_id if subnet_key in data: send_data['neutron_subnet_id'] = data[subnet_key] share_network = manila.share_network_create(request, **send_data) messages.success(request, _('Successfully created share' ' network: %s') % send_data['name']) return share_network except Exception: exceptions.handle(request, _('Unable to create share network.')) return False class Update(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Share Name")) description = forms.CharField(widget=forms.Textarea, label=_("Description"), required=False) def handle(self, request, data, *args, **kwargs): share_net_id = self.initial['share_network_id'] try: manila.share_network_update(request, share_net_id, name=data['name'], description=data['description']) message = _('Updating share network "%s"') % data['name'] messages.info(request, message) return True except Exception: redirect = reverse("horizon:project:shares:index") exceptions.handle(request, _('Unable to update share network.'), redirect=redirect) class AddSecurityServiceForm(forms.SelfHandlingForm): sec_service = forms.MultipleChoiceField( label=_("Networks"), required=True, widget=forms.CheckboxSelectMultiple(), error_messages={ 'required': _( "At least one security service" " must be specified.")}) def __init__(self, request, *args, **kwargs): super(AddSecurityServiceForm, self).__init__( request, *args, **kwargs) sec_services_choices = manila.security_service_list(request) self.fields['sec_service'].choices = [(' ', ' ')] + \ [(choice.id, choice.name or choice.id) for choice in sec_services_choices] def handle(self, request, data): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/panel.py0000664000175000017500000000165500000000000025724 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class ShareNetworks(horizon.Panel): name = _("Share Networks") slug = 'share_networks' permissions = ( 'openstack.services.share', ) dashboard.Project.register(ShareNetworks) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/tables.py0000664000175000017500000001035500000000000026074 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import tables from openstack_dashboard.api import base from openstack_dashboard.api import neutron from manila_ui.api import manila DELETABLE_STATES = ("INACTIVE", "ERROR") EDITABLE_STATES = ("INACTIVE", ) class Create(tables.LinkAction): name = "create_share_network" verbose_name = _("Create Share Network") url = "horizon:project:share_networks:share_network_create" classes = ("ajax-modal", "btn-create") icon = "plus" policy_rules = (("share", "share_network:create"),) class Delete(tables.DeleteAction): policy_rules = (("share", "share_network:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Network", u"Delete Share Networks", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Network", u"Deleted Share Networks", count ) def delete(self, request, obj_id): manila.share_network_delete(request, obj_id) def allowed(self, request, obj=None): if obj: # NOTE: leave it True until statuses become used # return obj.status in DELETABLE_STATES return True return True class EditShareNetwork(tables.LinkAction): name = "edit" verbose_name = _("Edit Share Network") url = "horizon:project:share_networks:share_network_update" classes = ("ajax-modal", "btn-create") policy_rules = (("share", "share_network:update"),) def allowed(self, request, obj_id): # sn = manila.share_network_get(request, obj_id) # return sn.status in EDITABLE_STATES # NOTE: leave it always True, until statuses become used return True class UpdateRow(tables.Row): ajax = True def get_data(self, request, share_net_id): share_net = manila.share_network_get(request, share_net_id) neutron_enabled = base.is_service_enabled(request, 'network') if neutron_enabled: share_net.neutron_net = neutron.network_get( request, share_net.neutron_net_id).name_or_id share_net.neutron_subnet = neutron.subnet_get( request, share_net.neutron_subnet_id).name_or_id return share_net class ShareNetworksTable(tables.DataTable): STATUS_CHOICES = ( ("ACTIVE", True), ("INACTIVE", True), ("ERROR", False), ) STATUS_DISPLAY_CHOICES = ( ("ACTIVE", pgettext_lazy("Current status of share network", u"Active")), ("INACTIVE", pgettext_lazy("Current status of share network", u"Inactive")), ("ERROR", pgettext_lazy("Current status of share network", u"Error")), ) name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:project:share_networks:share_network_detail") description = tables.WrappingColumn( "description", verbose_name=_("Description")) def get_object_display(self, share_network): return share_network.name or str(share_network.id) def get_object_id(self, share_network): return str(share_network.id) class Meta(object): name = "share_networks" verbose_name = _("Share Networks") table_actions = ( tables.NameFilterAction, Create, Delete, ) row_class = UpdateRow row_actions = ( EditShareNetwork, Delete, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/tabs.py0000664000175000017500000000200400000000000025543 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class OverviewTab(tabs.Tab): name = _("Overview") slug = "overview" template_name = "project/share_networks/_detail.html" def get_context_data(self, request): return {"share_network": self.tab_group.kwargs['share_network']} class ShareNetworkDetailTabs(tabs.TabGroup): slug = "share_network_details" tabs = ( OverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/0000775000175000017500000000000000000000000026242 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8186514 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/0000775000175000017500000000000000000000000031300 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/_create.html0000664000175000017500000000050400000000000033567 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% blocktrans trimmed %} Share networks contain network data, that will be used for creation of service VM, where will be hosted shares. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/_detail.html0000664000175000017500000000570600000000000033577 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}
{% trans "Name" %}
{{ share_network.name }}
{% if share_network.description %}
{% trans "Description" %}
{{ share_network.description }}
{% endif %} {% if share_network.created_at %}
{% trans "Created At" %}
{{ share_network.created_at }}
{% endif %} {% if share_network.updated_at %}
{% trans "Updated At" %}
{{ share_network.updated_at }}
{% endif %}
{% trans "Share Network ID" %}
{{ share_network.id }}
{% trans "Project ID" %}
{{ share_network.project_id }}

{% trans "Subnets" %}


{% for subnet in share_network.share_network_subnets %}
{% trans "Id" %}
{{subnet.id}}
{% if subnet.neutron_net != "Unknown" %} {% url 'horizon:project:networks:detail' subnet.neutron_net_id as network_detail_url %}
{% trans "Neutron Network" %}
{{subnet.neutron_net}}
{% endif %} {% if subnet.neutron_subnet != "Unknown" %} {% url 'horizon:project:networks:subnets:detail' subnet.neutron_subnet_id as subnet_detail_url %}
{% trans "Neutron Subnet" %}
{{subnet.neutron_subnet}}
{% endif %}
{% trans "Availability Zone" %}
{{subnet.availability_zone}}
{% endfor %}
{% if share_network.share_servers %}

{% trans "Share Servers" %}


{% for server in share_network.share_servers %}
    {% url 'horizon:admin:share_servers:share_server_detail' server.id as server_url %}
  • {{server.id }}
{% endfor %}
{% endif %} {% if share_network.sec_services %}

{% trans "Security Services" %}


{% for sec_service in share_network.sec_services %} {% url 'horizon:project:security_services:security_service_detail' sec_service.id as sec_service_url%}
{% trans "Id" %}
{{ sec_service.id }}
{% trans "Name" %}
{{ sec_service.name }}
{% trans "Type" %}
{{ sec_service.type }}

{% endfor %}
{% endif %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/_update.html0000664000175000017500000000164100000000000033611 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block form_id %}{% endblock %} {% block form_action %}{% url 'horizon:project:share_networks:share_network_update' share_network.id %}{% endblock %} {% block modal_id %}update_share_network_modal{% endblock %} {% block modal-header %}{% trans "Edit Share network" %}{% endblock %} {% block modal-body %}
{% include "horizon/common/_form_fields.html" %}

{% trans "Description" %}:

{% trans "From here you can modify name and description of a share network." %}

{% endblock %} {% block modal-footer %} {% trans "Cancel" %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/create.html0000664000175000017500000000030500000000000033427 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share Network" %}{% endblock %} {% block main %} {% include 'project/share_networks/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/detail.html0000664000175000017500000000034300000000000033430 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Network Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/index.html0000664000175000017500000000034700000000000033301 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Networks" %}{% endblock %} {% block main %}
{{ share_networks_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/templates/share_networks/update.html0000664000175000017500000000027700000000000033456 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Update share network" %}{% endblock %} {% block main %} {% include 'horizon/common/_workflow.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/urls.py0000664000175000017500000000224700000000000025610 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.project.share_networks import views urlpatterns = [ re_path( r'^$', views.ShareNetworksView.as_view(), name='index'), re_path( r'^create_share_network$', views.Create.as_view(), name='share_network_create'), re_path( r'^(?P[^/]+)/update$', views.Update.as_view(), name='share_network_update'), re_path( r'^(?P[^/]+)$', views.Detail.as_view(), name='share_network_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/views.py0000664000175000017500000001407700000000000025764 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon import tabs from horizon.utils import memoized from horizon import workflows from openstack_dashboard.api import base from openstack_dashboard.api import neutron from manila_ui.api import manila from manila_ui.dashboards.project.share_networks import tables as sn_tables from manila_ui.dashboards.project.share_networks import tabs as sn_tabs import manila_ui.dashboards.project.share_networks.workflows as sn_workflows from manila_ui.dashboards import utils class ShareNetworksView(tables.MultiTableView): table_classes = ( sn_tables.ShareNetworksTable, ) template_name = "admin/share_networks/index.html" page_title = _("Share Networks") @memoized.memoized_method def get_share_networks_data(self): try: share_networks = manila.share_network_list( self.request, detailed=True) except Exception: share_networks = [] exceptions.handle( self.request, _("Unable to retrieve share networks")) return share_networks class Update(workflows.WorkflowView): workflow_class = sn_workflows.UpdateShareNetworkWorkflow template_name = "project/share_networks/update.html" success_url = 'horizon:project:share_networks:index' page_title = _('Update Share Network') def get_initial(self): return {'id': self.kwargs["share_network_id"]} def get_context_data(self, **kwargs): context = super(Update, self).get_context_data(**kwargs) context['id'] = self.kwargs['share_network_id'] return context class Create(workflows.WorkflowView): workflow_class = sn_workflows.CreateShareNetworkWorkflow form_id = "create_share_network" submit_url = reverse_lazy( "horizon:project:share_networks:share_network_create") success_url = reverse_lazy("horizon:project:share_networks:index") page_title = _('Create Share Network') class Detail(tabs.TabView): tab_group_class = sn_tabs.ShareNetworkDetailTabs template_name = 'project/share_networks/detail.html' redirect_url = reverse_lazy('horizon:project:share_networks:index') def get_context_data(self, **kwargs): context = super(Detail, self).get_context_data(**kwargs) share_network = self.get_data() share_network_display_name = share_network.name or share_network.id context["share_network"] = share_network context["share_network_display_name"] = share_network_display_name context["page_title"] = _("Share Network Details: " "%(network_display_name)s") % \ {'network_display_name': share_network_display_name} return context @memoized.memoized_method def get_data(self): try: share_net_id = self.kwargs['share_network_id'] share_net = manila.share_network_get(self.request, share_net_id) if base.is_service_enabled(self.request, 'network'): for subnet in share_net.share_network_subnets: # Neutron Net ID try: subnet["neutron_net"] = neutron.network_get( self.request, subnet["neutron_net_id"]).name_or_id except ( neutron.neutron_client.exceptions .NeutronClientException ): subnet["neutron_net"] = _("Unknown") # Neutron Subnet ID try: subnet["neutron_subnet"] = neutron.subnet_get( self.request, subnet["neutron_subnet_id"]).name_or_id except ( neutron.neutron_client.exceptions .NeutronClientException ): subnet["neutron_subnet"] = _("Unknown") # List all azs if availability_zone is None availability_zones = manila.availability_zone_list(self.request) az_list = ", ".join([az.name for az in availability_zones]) for subnet in share_net.share_network_subnets: if subnet["availability_zone"] is None: subnet["availability_zone"] = az_list share_net.sec_services = ( manila.share_network_security_service_list( self.request, share_net_id)) for ss in share_net.sec_services: ss.type = utils.get_nice_security_service_type(ss) server_search_opts = {'share_network_id': share_net_id} try: share_servs = manila.share_server_list( self.request, search_opts=server_search_opts) # Non admins won't be able to get share servers except Exception: share_servs = [] if share_servs: share_net.share_servers = share_servs except Exception: exceptions.handle(self.request, _('Unable to retrieve share network details.'), redirect=self.redirect_url) return share_net def get_tabs(self, request, *args, **kwargs): share_network = self.get_data() return self.tab_group_class(request, share_network=share_network, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_networks/workflows.py0000664000175000017500000002766700000000000026675 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from horizon import workflows from openstack_dashboard import api from openstack_dashboard.api import base from manila_ui.api import manila from manila_ui.dashboards import utils class CreateShareNetworkInfoAction(workflows.Action): share_network_name = forms.CharField( max_length=255, label=_("Name"), required=True) share_network_description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) class Meta(object): name = ("Share Network") class CreateShareNetworkInfoStep(workflows.Step): action_class = CreateShareNetworkInfoAction contributes = ("share_network_description", "share_network_name") class AddShareNetworkSubnetAction(workflows.MembershipAction): availability_zone = forms.ChoiceField( required=False, label=_('Availability Zone'), widget=forms.ThemableSelectWidget(attrs={ 'data-availability_zone': _('Availability Zone')})) neutron_net_id = forms.ChoiceField( required=False, label=_('Neutron Net'), widget=forms.ThemableSelectWidget(attrs={ 'class': 'switchable', 'data-slug': 'neutron_net_id', 'data-neutron_net_id': _('Neutron Net')})) class Meta(object): name = _("Subnet") help_text = _("Specify an Availability Zone or an existing subnet. " "If no details are specified, " "then a default subnet with a null Availability " "Zone will be created automatically.") def __init__(self, request, context, *args, **kwargs): super().__init__(request, context, *args, **kwargs) self.fields['availability_zone'].choices = ( self.get_availability_zone_choices(request) ) self.neutron_enabled = base.is_service_enabled(request, 'network') if self.neutron_enabled: try: self.fields['neutron_net_id'].choices, networks = ( self.get_neutron_net_id_choices(request) ) except Exception: msg = _('Unable to initialize neutron networks.') exceptions.handle(request, msg) try: self.get_neutron_subnet_id_choices(request, networks) except Exception: msg = _('Unable to initialize neutron subnets.') exceptions.handle(request, msg) def get_availability_zone_choices(self, request): availability_zone_choices = [('', _('None'))] for availability_zone in manila.availability_zone_list(request): availability_zone_choices.append( (availability_zone.id, availability_zone.name) ) return availability_zone_choices def get_neutron_net_id_choices(self, request): net_choices = [('', _('None'))] networks = api.neutron.network_list(request) for network in networks: net_choices.append((utils.transform_dashed_name(network.id), network.name_or_id)) return net_choices, networks def get_neutron_subnet_id_choices(self, request, networks): for net in networks: subnet_field_name = ( 'subnet-choices-%s' % utils.transform_dashed_name(net.id)) data_net_id = ( 'data-neutron_net_id-%s' % utils.transform_dashed_name(net.id)) subnet_field = forms.ChoiceField( required=False, choices=(), label=_('Neutron Subnet'), widget=forms.ThemableSelectWidget(attrs={ 'class': 'switched', 'data-switch-on': 'neutron_net_id', data_net_id: _('Neutron Subnet')})) self.fields[subnet_field_name] = subnet_field subnet_choices = api.neutron.subnet_list(request, network_id=net.id) self.fields[subnet_field_name].choices = [ (choice.id, choice.name_or_id) for choice in subnet_choices] def hide_neutron_subnet_id_choices(self): self.fields['neutron_subnet_id'].choices = [] self.fields['neutron_subnet_id'].widget = forms.HiddenInput() class AddShareNetworkSubnetStep(workflows.Step): action_class = AddShareNetworkSubnetAction contributes = ("neutron_net_id", "neutron_subnet_id", "availability_zone") class CreateShareNetworkWorkflow(workflows.Workflow): slug = "create_share_network" name = _("Create Share Network") finalize_button_name = _("Create Share Network") success_message = _('Created share network "%s".') failure_message = _('Unable to create share network "%s".') success_url = 'horizon:project:share_networks:index' default_steps = (CreateShareNetworkInfoStep, AddShareNetworkSubnetStep) wizard = True def handle(self, request, context): try: data = request.POST send_data = {'name': context['share_network_name']} if context['share_network_description']: send_data['description'] = context['share_network_description'] neutron_net_id = context.get('neutron_net_id') if neutron_net_id: send_data['neutron_net_id'] = utils.transform_dashed_name( neutron_net_id.strip()) subnet_key = ( 'subnet-choices-%s' % neutron_net_id.strip() ) if data.get(subnet_key) is not None: send_data['neutron_subnet_id'] = data.get(subnet_key) if context['availability_zone']: send_data['availability_zone'] = context['availability_zone'] share_network = manila.share_network_create(request, **send_data) messages.success(request, _('Successfully created share' ' network: %s') % send_data['name']) return share_network except Exception: exceptions.handle(request, _('Unable to create share network.')) return False class UpdateShareNetworkInfoAction(workflows.Action): name = forms.CharField(label=_("Name"), max_length=255) description = forms.CharField(label=_("Description"), max_length=255, required=False) def __init__(self, request, *args, **kwargs): super(UpdateShareNetworkInfoAction, self).__init__( request, *args, **kwargs) share_network = manila.share_network_get(request, self.initial['id']) self.fields['name'].initial = share_network.name self.fields['description'].initial = share_network.description class Meta(object): name = _("Share Network Info") help_text = _("From here you can update share network info. ") slug = "update-share_network_info" def clean(self): cleaned_data = super(UpdateShareNetworkInfoAction, self).clean() return cleaned_data class UpdateShareNetworkInfoStep(workflows.Step): action_class = UpdateShareNetworkInfoAction contributes = ("description", "name") class AddSecurityServiceAction(workflows.MembershipAction): def __init__(self, request, *args, **kwargs): super(AddSecurityServiceAction, self).__init__(request, *args, **kwargs) err_msg = _('Unable to get the security services hosts') default_role_field_name = self.get_default_role_field_name() self.fields[default_role_field_name] = forms.CharField(required=False) self.fields[default_role_field_name].initial = 'member' field_name = self.get_member_field_name('member') self.fields[field_name] = forms.MultipleChoiceField(required=False) share_network_id = self.initial['id'] security_services = manila.share_network_security_service_list( request, share_network_id) sec_services_initial = [sec_service.id for sec_service in security_services] sec_services = [] try: sec_services = manila.security_service_list(request) except Exception: exceptions.handle(request, err_msg) sec_services_choices = [(sec_service.id, sec_service.name or sec_service.id) for sec_service in sec_services] self.fields[field_name].choices = sec_services_choices self.fields[field_name].initial = sec_services_initial class Meta(object): name = _("Security services within share network") slug = "add_security_service" class AddSecurityServiceStep(workflows.UpdateMembersStep): action_class = AddSecurityServiceAction help_text = _("Add security services to share network.") available_list_title = _("Available security services") members_list_title = _("Selected security services") no_available_text = _("No security services found.") no_members_text = _("No security services selected.") show_roles = False depends_on = ("id",) contributes = ("security_services",) def contribute(self, data, context): if data: member_field_name = self.get_member_field_name('member') context['security_service'] = data.get(member_field_name, []) return context class UpdateShareNetworkWorkflow(workflows.Workflow): slug = "update_share_network" name = _("Update Share Network") finalize_button_name = _("Update Share Network") success_message = _('Updated share network "%s".') failure_message = _('Unable to update share network "%s".') success_url = 'horizon:project:share_networks:index' default_steps = (UpdateShareNetworkInfoStep, AddSecurityServiceStep) def format_status_message(self, message): return message % self.context['name'] def handle(self, request, context): try: manila.share_network_update(request, context['id'], description=context['description'], name=context['name']) sec_services = manila.security_service_list(request, search_opts={ 'share_network_id': context['id']}) sec_services_old = set([sec_service.id for sec_service in sec_services]) sec_services_new = set(context['security_service']) for sec_service in sec_services_new - sec_services_old: manila.share_network_security_service_add(request, context['id'], sec_service) for sec_service in sec_services_old - sec_services_new: manila.share_network_security_service_remove(request, context['id'], sec_service) return True except Exception: exceptions.handle(request, _('Unable to update share network.')) return False ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8226514 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/0000775000175000017500000000000000000000000024412 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/__init__.py0000664000175000017500000000000000000000000026511 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/forms.py0000664000175000017500000000730000000000000026112 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. """ Views for managing share snapshots. """ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class CreateShareSnapshotForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Share Snapshot Name")) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def __init__(self, request, *args, **kwargs): super(self.__class__, self).__init__(request, *args, **kwargs) # populate share_id share_id = kwargs.get('initial', {}).get('share_id', []) self.fields['share_id'] = forms.CharField( widget=forms.HiddenInput(), initial=share_id) def handle(self, request, data): try: snapshot = manila.share_snapshot_create( request, data['share_id'], data['name'], data['description']) message = _('Creating share snapshot "%s".') % data['name'] messages.success(request, message) return snapshot except Exception: redirect = reverse("horizon:project:share_snapshots:index") exceptions.handle(request, _('Unable to create share snapshot.'), redirect=redirect) class UpdateShareSnapshotForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Share Snapshot Name")) description = forms.CharField( widget=forms.Textarea, label=_("Description"), required=False) def handle(self, request, data): snapshot_id = self.initial['snapshot_id'] try: manila.share_snapshot_update( request, snapshot_id, data['name'], data['description']) message = _('Updating share snapshot "%s"') % data['name'] messages.success(request, message) return True except Exception: exceptions.handle(request, _('Unable to update share snapshot.')) class AddShareSnapshotRule(forms.SelfHandlingForm): access_type = forms.ChoiceField( label=_("Access Type"), required=True, choices=(('ip', 'ip'), ('user', 'user'), ('cephx', 'cephx'), ('cert', 'cert'))) access_to = forms.CharField( label=_("Access To"), max_length="255", required=True) def handle(self, request, data): snapshot_id = self.initial['snapshot_id'] try: manila.share_snapshot_allow( request, snapshot_id, access_to=data['access_to'], access_type=data['access_type']) message = _('Creating snapshot rule for "%s"') % data['access_to'] messages.success(request, message) return True except Exception: redirect = reverse( "horizon:project:share_snapshots:share_snapshot_manage_rules", args=[self.initial['snapshot_id']]) exceptions.handle( request, _('Unable to add snapshot rule.'), redirect=redirect) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/panel.py0000664000175000017500000000166100000000000026067 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class ShareSnapshots(horizon.Panel): name = _("Share Snapshots") slug = 'share_snapshots' permissions = ( 'openstack.services.share', ) dashboard.Project.register(ShareSnapshots) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/tables.py0000664000175000017500000002374600000000000026252 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.template.defaultfilters import title from django.urls import reverse from django.utils.http import urlencode from django.utils.text import format_lazy from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import exceptions from horizon import tables from manila_ui.api import manila DELETABLE_STATES = ("available", "error") class UpdateShareSnapshotRow(tables.Row): ajax = True def get_data(self, request, snapshot_id): snapshot = manila.share_snapshot_get(request, snapshot_id) if not snapshot.name: snapshot.name = snapshot_id return snapshot def get_size(snapshot): return _("%sGiB") % snapshot.size class CreateShareSnapshot(tables.LinkAction): name = "create_share_snapshot" verbose_name = _("Create Share Snapshot") url = "horizon:project:share_snapshots:share_snapshot_create" classes = ("ajax-modal", "btn-camera") policy_rules = (("share", "share:create_snapshot"),) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "project_id", None) return {"project_id": project_id} def allowed(self, request, share=None): usages = manila.tenant_absolute_limits(request) snapshots_allowed = (usages['maxTotalShareSnapshots'] > usages['totalShareSnapshotsUsed'] and usages['maxTotalSnapshotGigabytes'] > usages['totalSnapshotGigabytesUsed']) if not snapshots_allowed: if "disabled" not in self.classes: self.classes = [c for c in self.classes] + ['disabled'] self.verbose_name = format_lazy( '{verbose_name} {quota_exceeded}', verbose_name=self.verbose_name, quota_exceeded=_("(Quota exceeded)")) else: self.verbose_name = _("Create Share Snapshot") classes = [c for c in self.classes if c != "disabled"] self.classes = classes # NOTE(vponomaryov): Disable form with creation of a snapshot for # shares that has attr 'snapshot_support' equal to False. if hasattr(share, 'snapshot_support'): snapshot_support = share.snapshot_support else: # NOTE(vponomaryov): Allow creation of a snapshot for shares that # do not have such attr for backward compatibility. snapshot_support = True return share.status in ("available", "in-use") and snapshot_support class DeleteShareSnapshot(tables.DeleteAction): policy_rules = (("share", "share:delete_snapshot"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Snapshot", u"Delete Share Snapshots", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Snapshot", u"Deleted Share Snapshots", count ) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "project_id", None) return {"project_id": project_id} def delete(self, request, obj_id): obj = self.table.get_object_by_id(obj_id) name = self.table.get_object_display(obj) try: manila.share_snapshot_delete(request, obj_id) except Exception: msg = _('Unable to delete snapshot "%s". One or more shares ' 'depend on it.') exceptions.handle(self.request, msg % name) raise def allowed(self, request, snapshot=None): if snapshot: return snapshot.status in DELETABLE_STATES return True class CreateShareFromShareSnapshot(tables.LinkAction): name = "create_share_from_share_snapshot" verbose_name = _("Create Share") url = "horizon:project:shares:create" classes = ("ajax-modal", "btn-camera") policy_rules = (("share", "share:create"),) def get_link_url(self, datum): base_url = reverse(self.url) params = urlencode({"snapshot_id": self.table.get_object_id(datum)}) return "?".join([base_url, params]) def allowed(self, request, share=None): return share.status == "available" class EditShareSnapshot(tables.LinkAction): name = "edit_share_snapshot" verbose_name = _("Edit Share Snapshot") url = "horizon:project:share_snapshots:share_snapshot_edit" classes = ("ajax-modal", "btn-camera") class ShareSnapshotShareNameColumn(tables.Column): def get_link_url(self, snapshot): return reverse(self.link, args=(snapshot.share_id,)) class ManageShareSnapshotRules(tables.LinkAction): name = "share_snapshot_manage_rules" verbose_name = _("Manage Share Snapshot Rules") url = "horizon:project:share_snapshots:share_snapshot_manage_rules" classes = ("btn-edit",) policy_rules = (("share", "share:access_get_all"),) def allowed(self, request, snapshot=None): share = manila.share_get(request, snapshot.share_id) return share.mount_snapshot_support class AddShareSnapshotRule(tables.LinkAction): name = "share_snapshot_rule_add" verbose_name = _("Add Share Snapshot Rule") url = 'horizon:project:share_snapshots:share_snapshot_rule_add' classes = ("ajax-modal", "btn-create") icon = "plus" policy_rules = (("share", "share:allow_access"),) def allowed(self, request, snapshot=None): snapshot = manila.share_snapshot_get( request, self.table.kwargs['snapshot_id']) return snapshot.status in ("available", "in-use") def get_link_url(self): return reverse(self.url, args=[self.table.kwargs['snapshot_id']]) class DeleteShareSnapshotRule(tables.DeleteAction): policy_rules = (("share", "share:deny_access"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share Snapshot Rule", u"Delete Share Snapshot Rules", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share Snapshot Rule", u"Deleted Share Snapshot Rules", count ) def delete(self, request, obj_id): try: manila.share_snapshot_deny( request, self.table.kwargs['snapshot_id'], obj_id) except Exception: msg = _('Unable to delete snapshot rule "%s".') % obj_id exceptions.handle(request, msg) class UpdateShareSnapshotRuleRow(tables.Row): ajax = True def get_data(self, request, rule_id): rules = manila.share_snapshot_rules_list( request, self.table.kwargs['snapshot_id']) if rules: for rule in rules: if rule.id == rule_id: return rule raise exceptions.NotFound class ShareSnapshotRulesTable(tables.DataTable): access_type = tables.Column("access_type", verbose_name=_("Access Type")) access_to = tables.Column("access_to", verbose_name=_("Access to")) status = tables.Column("state", verbose_name=_("Status")) def get_object_display(self, obj): return obj.id class Meta(object): name = "rules" verbose_name = _("Share Snapshot Rules") status_columns = ["status"] row_class = UpdateShareSnapshotRuleRow table_actions = ( AddShareSnapshotRule, DeleteShareSnapshotRule, ) row_actions = ( DeleteShareSnapshotRule, ) class ShareSnapshotsTable(tables.DataTable): STATUS_CHOICES = ( ("in-use", True), ("available", True), ("creating", None), ("error", False), ) STATUS_DISPLAY_CHOICES = ( ("in-use", pgettext_lazy("Current status of snapshot", u"In-use")), ("available", pgettext_lazy("Current status of snapshot", u"Available")), ("creating", pgettext_lazy("Current status of snapshot", u"Creating")), ("error", pgettext_lazy("Current status of snapshot", u"Error")), ) name = tables.Column( "name", verbose_name=_("Name"), link="horizon:project:share_snapshots:share_snapshot_detail") description = tables.Column( "description", verbose_name=_("Description"), truncate=40) size = tables.Column( get_size, verbose_name=_("Size"), attrs={'data-type': 'size'}) status = tables.Column( "status", filters=(title,), verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) source = ShareSnapshotShareNameColumn( "share", verbose_name=_("Source"), link="horizon:project:shares:detail") def get_object_display(self, obj): return obj.name class Meta(object): name = "share_snapshots" verbose_name = _("Share Snapshots") status_columns = ["status"] row_class = UpdateShareSnapshotRow table_actions = ( tables.NameFilterAction, DeleteShareSnapshot, ) row_actions = ( EditShareSnapshot, CreateShareFromShareSnapshot, ManageShareSnapshotRules, DeleteShareSnapshot, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/tabs.py0000664000175000017500000000207100000000000025715 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ShareSnapshotOverviewTab(tabs.Tab): name = _("Share Snapshot Overview") slug = "share_snapshot_overview_tab" template_name = "project/share_snapshots/_detail.html" def get_context_data(self, request): return {"snapshot": self.tab_group.kwargs['snapshot']} class ShareSnapshotDetailTabs(tabs.TabGroup): slug = "share_snapshot_details" tabs = ( ShareSnapshotOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/0000775000175000017500000000000000000000000026410 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8226514 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/0000775000175000017500000000000000000000000031614 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_create.html0000664000175000017500000000036300000000000034106 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}
{% include "project/share_snapshots/_limits.html" with usages=usages snapshot_quota=True %}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_detail.html0000664000175000017500000000414300000000000034105 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Snapshot Overview" %}


{% trans "Name" %}
{{ snapshot.name }}
{% trans "ID" %}
{{ snapshot.id }}
{% url 'horizon:project:shares:detail' snapshot.share_id as share_url %}
{% trans "Source" %}
{{ snapshot.share_name_or_id }}
{% if snapshot.description %}
{% trans "Description" %}
{{ snapshot.description }}
{% endif %}
{% trans "Status" %}
{{ snapshot.status|capfirst }}
{% if snapshot.export_locations %}
{% trans "Export locations" %}
{% for el in snapshot.export_locations %}

{% trans "Path:" %}
{% if el.is_admin_only != None %}
{% trans "Is admin only:" %} {{ el.is_admin_only }}
{% endif %} {% if el.share_snapshot_instance_id %}
{% trans "Snapshot Replica ID:" %} {{ el.share_snapshot_instance_id }}
{% endif %}

{% endfor %} {% endif %}
{% if snapshot.rules != None %}

{% trans "Access Rules" %}


{% for rule in snapshot.rules %}
{{ rule.access_type }}

{% trans "Access to:" %} {{ rule.access_to }}
{% trans "Status:" %} {{ rule.state }}

{% endfor %}
{% endif %}

{% trans "Specs" %}


{% trans "Size" %}
{{ snapshot.size }} {% trans "GiB" %}
{% trans "Created" %}
{{ snapshot.created_at|parse_date }}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_limits.html0000664000175000017500000000237600000000000034152 0ustar00zuulzuul00000000000000{% load i18n horizon humanize %}

{% trans "Description" %}:

{% trans "Share Snapshots are used for storing share changes and creating shares. " %}

{% trans "Share Limits" %}

{% trans "Total Gibibytes" %} ({{ usages.totalShareGigabytesUsed|intcomma }} {% trans "GiB" %})

{{ usages.maxTotalShareGigabytes|quota:_("GiB")|intcomma }}

{% trans "Number of Share Snapshots" %} ({{ usages.totalShareSnapshotsUsed|intcomma }})

{{ usages.maxTotalShareSnapshots|quota|intcomma }}

././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_rule_add.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_rule_add.ht0000664000175000017500000000063600000000000034074 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% blocktrans trimmed %} Add policy rule to snapshot, 'ip' rule represents ip address, 'user' rule represents username or usergroup, 'cephx' rule represents ceph auth ID, and 'cert' rule represents certificate. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_update.html0000664000175000017500000000034600000000000034126 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can modify name and description of a snapshot." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/create.html0000664000175000017500000000030700000000000033745 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share Snapshot" %}{% endblock %} {% block main %} {% include 'project/share_snapshots/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/detail.html0000664000175000017500000000034400000000000033745 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Snapshot Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/index.html0000664000175000017500000000035100000000000033610 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Snapshots" %}{% endblock %} {% block main %}
{{ share_snapshots_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000021100000000000011447 xustar0000000000000000115 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/manage_rules.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/manage_rules0000664000175000017500000000024200000000000034177 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Snapshot Rules" %}{% endblock %} {% block main %} {{ table.render }} {% endblock %} ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/rule_add.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/rule_add.htm0000664000175000017500000000027400000000000034110 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Add Rule" %}{% endblock %} {% block main %} {% include 'project/share_snapshots/_rule_add.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/update.html0000664000175000017500000000030500000000000033762 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Edit Share Snapshot" %}{% endblock %} {% block main %} {% include 'project/share_snapshots/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/urls.py0000664000175000017500000000311000000000000025744 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.project.share_snapshots import views urlpatterns = [ re_path( r'^$', views.ShareSnapshotsView.as_view(), name='index'), re_path( r'^(?P[^/]+)/share_snapshot_create/$', views.CreateShareSnapshotView.as_view(), name='share_snapshot_create'), re_path( r'^(?P[^/]+)/share_snapshot_edit/$', views.UpdateShareSnapshotView.as_view(), name='share_snapshot_edit'), re_path( r'^(?P[^/]+)$', views.ShareSnapshotDetailView.as_view(), name='share_snapshot_detail'), re_path( r'^(?P[^/]+)/share_snapshot_rules/$', views.ManageShareSnapshotRulesView.as_view(), name='share_snapshot_manage_rules'), re_path( r'^(?P[^/]+)/share_snapshot_rule_add/$', views.AddShareSnapshotRuleView.as_view(), name='share_snapshot_rule_add'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/share_snapshots/views.py0000664000175000017500000002236700000000000026133 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.project.share_snapshots import forms as ss_forms from manila_ui.dashboards.project.share_snapshots import tables as ss_tables from manila_ui.dashboards.project.share_snapshots import tabs as ss_tabs from manila_ui.dashboards import utils as ui_utils class ShareSnapshotsView(tables.MultiTableView): table_classes = ( ss_tables.ShareSnapshotsTable, ) template_name = "project/share_snapshots/index.html" page_title = _("Share Snapshots") @memoized.memoized_method def get_share_snapshots_data(self): try: snapshots = manila.share_snapshot_list(self.request) shares = manila.share_list(self.request) share_names = dict([(share.id, share.name or share.id) for share in shares]) for snapshot in snapshots: snapshot.share = share_names.get(snapshot.share_id) except Exception: msg = _("Unable to retrieve share snapshots list.") exceptions.handle(self.request, msg) return [] # Gather our tenants to correlate against IDs return snapshots class ShareSnapshotDetailView(tabs.TabView): tab_group_class = ss_tabs.ShareSnapshotDetailTabs template_name = 'project/share_snapshots/detail.html' redirect_url = reverse_lazy('horizon:project:share_snapshots:index') def get_context_data(self, **kwargs): context = super(ShareSnapshotDetailView, self).get_context_data( **kwargs) snapshot = self.get_data() snapshot_display_name = snapshot.name or snapshot.id context["snapshot"] = snapshot context["snapshot_display_name"] = snapshot_display_name context["page_title"] = _("Snapshot Details: " "%(snapshot_display_name)s") % ( {'snapshot_display_name': snapshot_display_name}) return context @memoized.memoized_method def get_data(self): try: snapshot_id = self.kwargs['snapshot_id'] snapshot = manila.share_snapshot_get(self.request, snapshot_id) share = manila.share_get(self.request, snapshot.share_id) if share.mount_snapshot_support: snapshot.rules = manila.share_snapshot_rules_list( self.request, snapshot_id) snapshot.export_locations = ( manila.share_snap_export_location_list( self.request, snapshot)) export_locations = [ exp['path'] for exp in snapshot.export_locations ] snapshot.el_size = ui_utils.calculate_longest_str_size( export_locations) snapshot.share_name_or_id = share.name or share.id except Exception: exceptions.handle( self.request, _('Unable to retrieve snapshot details.'), redirect=self.redirect_url) return snapshot def get_tabs(self, request, *args, **kwargs): snapshot = self.get_data() return self.tab_group_class(request, snapshot=snapshot, **kwargs) class CreateShareSnapshotView(forms.ModalFormView): form_class = ss_forms.CreateShareSnapshotForm form_id = "create_share_snapshot" template_name = 'project/share_snapshots/create.html' modal_header = _("Create Share Snapshot") modal_id = "create_share_snapshot_modal" submit_label = _("Create Share Snapshot") submit_url = "horizon:project:share_snapshots:share_snapshot_create" success_url = reverse_lazy('horizon:project:share_snapshots:index') page_title = _('Create Share Snapshot') def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) context['share_id'] = self.kwargs['share_id'] try: context['usages'] = manila.tenant_absolute_limits(self.request) except Exception: exceptions.handle(self.request, _('Unable to retrieve quotas.')) return context def get_initial(self): self.submit_url = reverse(self.submit_url, kwargs=self.kwargs) return {'share_id': self.kwargs["share_id"]} class UpdateShareSnapshotView(forms.ModalFormView): form_class = ss_forms.UpdateShareSnapshotForm form_id = "update_share_snapshot" template_name = 'project/share_snapshots/update.html' modal_header = _("Update Share Snapshot") modal_id = "update_share_snapshot_modal" submit_label = _("Update") submit_url = "horizon:project:share_snapshots:share_snapshot_edit" success_url = reverse_lazy('horizon:project:share_snapshots:index') page_title = _('Edit Share Snapshot') @memoized.memoized_method def get_object(self): if not hasattr(self, "_object"): snap_id = self.kwargs['snapshot_id'] try: self._object = manila.share_snapshot_get(self.request, snap_id) except Exception: msg = _('Unable to retrieve share snapshot.') url = reverse('horizon:project:share_snapshots:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): snapshot = self.get_object() return {'snapshot_id': self.kwargs["snapshot_id"], 'name': snapshot.name, 'description': snapshot.description} class AddShareSnapshotRuleView(forms.ModalFormView): form_class = ss_forms.AddShareSnapshotRule form_id = "rule_add_snap" template_name = 'project/share_snapshots/rule_add.html' modal_header = _("Add Rule") modal_id = "rule_add_share_snapshot_modal" submit_label = _("Add") submit_url = "horizon:project:share_snapshots:share_snapshot_rule_add" success_url = reverse_lazy("horizon:project:share_snapshots:index") page_title = _('Add Rule') def get_object(self): if not hasattr(self, "_object"): snapshot_id = self.kwargs['snapshot_id'] try: self._object = manila.share_snapshot_get( self.request, snapshot_id) except Exception: msg = _('Unable to retrieve snapshot.') url = reverse('horizon:project:share_snapshots:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): snapshot = self.get_object() return {'snapshot_id': self.kwargs["snapshot_id"], 'name': snapshot.name, 'description': snapshot.description} def get_success_url(self): return reverse( "horizon:project:share_snapshots:share_snapshot_manage_rules", args=[self.kwargs['snapshot_id']]) class ManageShareSnapshotRulesView(tables.DataTableView): table_class = ss_tables.ShareSnapshotRulesTable template_name = 'project/share_snapshots/manage_rules.html' def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) snapshot = manila.share_snapshot_get( self.request, self.kwargs['snapshot_id']) context['snapshot_display_name'] = snapshot.name or snapshot.id context["snapshot"] = self.get_data() context["page_title"] = _("Snapshot Rules: " "%(snapshot_display_name)s") % { 'snapshot_display_name': context['snapshot_display_name']} return context @memoized.memoized_method def get_data(self): try: snapshot_id = self.kwargs['snapshot_id'] rules = manila.share_snapshot_rules_list( self.request, snapshot_id) except Exception: redirect = reverse('horizon:project:share_snapshots:index') exceptions.handle( self.request, _('Unable to retrieve share snapshot rules.'), redirect=redirect) return rules ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8226514 manila-ui-11.0.0/manila_ui/dashboards/project/shares/0000775000175000017500000000000000000000000022473 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/__init__.py0000664000175000017500000000443400000000000024611 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import exceptions from openstack_dashboard.api import base from openstack_dashboard.usage import base as usage from manila_ui.api import manila # # Add extra pie charts to project/compute overview # class ManilaUsage(usage.ProjectUsage): def get_manila_limits(self): """Get share limits if manila is enabled.""" if not base.is_service_enabled(self.request, 'share'): return try: self.limits.update(manila.tenant_absolute_limits(self.request)) except Exception: msg = _("Unable to retrieve share limit information.") exceptions.handle(self.request, msg) return def get_limits(self): super(self.__class__, self).get_limits() self.get_manila_limits() def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) types = ( ("totalSharesUsed", "maxTotalShares", _("Shares")), ("totalShareGigabytesUsed", "maxTotalShareGigabytes", _("Share Storage")), ("totalShareSnapshotsUsed", "maxTotalShareSnapshots", _("Share Snapshots")), ("totalSnapshotGigabytesUsed", "maxTotalSnapshotGigabytes", _("Share Snapshots Storage")), ("totalShareNetworksUsed", "maxTotalShareNetworks", _("Share Networks")), ) for t in types: if t[0] in self.usage.limits and t[1] in self.usage.limits: context['charts'].append({ 'type': t[0], 'name': t[2], 'used': self.usage.limits[t[0]], 'max': self.usage.limits[t[1]], 'text': False, }) return context ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/forms.py0000664000175000017500000005337500000000000024210 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # 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. from django.conf import settings from django.forms import ValidationError from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from horizon.utils.memoized import memoized from manila_ui.api import manila from manila_ui.dashboards import utils from manila_ui import features from manilaclient.common.apiclient import exceptions as m_exceptions import time class CreateForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Share Name")) description = forms.CharField( label=_("Description"), required=False, widget=forms.Textarea(attrs={'rows': 3})) share_proto = forms.ChoiceField(label=_("Share Protocol"), required=True) size = forms.IntegerField(min_value=1, label=_("Size (GiB)")) share_type = forms.ChoiceField( label=_("Share Type"), required=True, widget=forms.Select( attrs={'class': 'switchable', 'data-slug': 'sharetype'})) availability_zone = forms.ChoiceField( label=_("Availability Zone"), required=False) def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) # NOTE(vkmc): choose only those share protocols that are enabled # FIXME(vkmc): this should be better implemented by having a # capabilities endpoint on the control plane. manila_features = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) self.enabled_share_protocols = manila_features.get( 'enabled_share_protocols', ['NFS', 'CIFS', 'GlusterFS', 'HDFS', 'CephFS', 'MapRFS']) self.enable_public_shares = manila_features.get( 'enable_public_shares', True) share_networks = manila.share_network_list(request) share_types = manila.share_type_list(request) self.fields['share_type'].choices = ( [(utils.transform_dashed_name(st.name), st.name) for st in share_types] ) availability_zones = manila.availability_zone_list(request) self.fields['availability_zone'].choices = ( [("", "")] + [(az.name, az.name) for az in availability_zones]) if features.is_share_groups_enabled(): share_groups = manila.share_group_list(request) self.fields['sg'] = forms.ChoiceField( label=_("Share Group"), choices=[("", "")] + [(sg.id, sg.name or sg.id) for sg in share_groups], required=False) self.sn_field_name_prefix = 'share-network-choices-' for st in share_types: extra_specs = st.get_keys() dhss = extra_specs.get('driver_handles_share_servers') # NOTE(vponomaryov): Set and tie share-network field only for # share types with enabled handling of share servers. if (isinstance(dhss, str) and dhss.lower() in ['true', '1']): sn_choices = ( [(sn.id, sn.name or sn.id) for sn in share_networks]) sn_field_name = ( self.sn_field_name_prefix + utils.transform_dashed_name(st.name) ) sn_field = forms.ChoiceField( label=_("Share Network"), required=True, choices=sn_choices, widget=forms.Select(attrs={ 'class': 'switched', 'data-switch-on': 'sharetype', 'data-sharetype-%s' % utils.transform_dashed_name( st.name): _("Share Network"), })) self.fields[sn_field_name] = sn_field self.fields['share_source_type'] = forms.ChoiceField( label=_("Share Source"), required=False, widget=forms.Select( attrs={'class': 'switchable', 'data-slug': 'source'})) self.fields['snapshot'] = forms.ChoiceField( label=_("Use snapshot as a source"), widget=forms.fields.SelectWidget( attrs={'class': 'switched', 'data-switch-on': 'source', 'data-source-snapshot': _('Snapshot')}, data_attrs=('size', 'name'), transform=lambda x: "%s (%sGiB)" % (x.name, x.size)), required=False) self.fields['metadata'] = forms.CharField( label=_("Metadata"), required=False, widget=forms.Textarea(attrs={'rows': 4})) if self.enable_public_shares: self.fields['is_public'] = forms.BooleanField( label=_("Make visible to users from all projects"), required=False) self.fields['share_proto'].choices = [(sp, sp) for sp in self.enabled_share_protocols] if ("snapshot_id" in request.GET or kwargs.get("data", {}).get("snapshot")): try: snapshot = self.get_snapshot( request, request.GET.get("snapshot_id", kwargs.get("data", {}).get("snapshot"))) self.fields['name'].initial = snapshot.name self.fields['size'].initial = snapshot.size self.fields['snapshot'].choices = ((snapshot.id, snapshot),) try: # Set the share type and az from the original share orig_share = manila.share_get(request, snapshot.share_id) self.fields['share_type'].initial = ( orig_share.share_type_name) self.fields['availability_zone'].initial = ( orig_share.availability_zone) except Exception: pass self.fields['size'].help_text = _( 'Share size must be equal to or greater than the snapshot ' 'size (%sGiB)') % snapshot.size del self.fields['share_source_type'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) else: source_type_choices = [] try: snapshot_list = manila.share_snapshot_list(request) snapshots = [s for s in snapshot_list if s.status == 'available'] if snapshots: source_type_choices.append(("snapshot", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot'].choices = choices else: del self.fields['snapshot'] except Exception: exceptions.handle(request, _("Unable to retrieve " "share snapshots.")) if source_type_choices: choices = ([('no_source_type', _("No source, empty share"))] + source_type_choices) self.fields['share_source_type'].choices = choices else: del self.fields['share_source_type'] def clean(self): cleaned_data = super(CreateForm, self).clean() form_errors = list(self.errors) chosen_share_type = cleaned_data.get('share_type') if chosen_share_type: # NOTE(vponomaryov): skip errors for share-network fields that are # not related to chosen share type. for error in form_errors: st_name = error.split(self.sn_field_name_prefix)[-1] if (error.startswith(self.sn_field_name_prefix) and st_name != chosen_share_type): cleaned_data[error] = 'Not set' self.errors.pop(error, None) cleaned_data['share_network'] = cleaned_data.get( self.sn_field_name_prefix + cleaned_data.get('share_type')) return cleaned_data def handle(self, request, data): try: snapshot_id = None source_type = data.get('share_source_type', None) share_network = data.get('share_network', None) if (data.get("snapshot", None) and source_type in [None, 'snapshot']): # Create from Snapshot snapshot = self.get_snapshot(request, data["snapshot"]) snapshot_id = snapshot.id if (data['size'] < snapshot.size): error_message = _('The share size cannot be less than the ' 'snapshot size (%sGiB)') % snapshot.size raise ValidationError(error_message) else: data['size'] = int(data['size']) metadata = {} try: set_dict, unset_list = utils.parse_str_meta(data['metadata']) if unset_list: msg = _("Expected only pairs of key=value.") raise ValidationError(message=msg) metadata = set_dict except ValidationError as e: self.api_error(e.messages[0]) return False is_public = self.enable_public_shares and data['is_public'] share = manila.share_create( request, size=data['size'], name=data['name'], description=data['description'], proto=data['share_proto'], share_network=share_network, snapshot_id=snapshot_id, share_type=utils.transform_dashed_name(data['share_type']), is_public=is_public, metadata=metadata, availability_zone=data.get('availability_zone') or None, share_group_id=data.get('sg') or None, ) message = _('Creating share "%s"') % data['name'] messages.success(request, message) return share except ValidationError as e: self.api_error(e.messages[0]) except m_exceptions.BadRequest as e: self.api_error(_("Unable to create share. %s") % e.message) except Exception: exceptions.handle(request, ignore=True) self.api_error(_("Unable to create share.")) return False @memoized def get_snapshot(self, request, id): return manila.share_snapshot_get(request, id) class UpdateForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Share Name")) description = forms.CharField(widget=forms.Textarea, label=_("Description"), required=False) is_public = forms.BooleanField( label=_("Make visible to users from all projects"), required=False) def __init__(self, request, *args, **kwargs): super(UpdateForm, self).__init__(request, *args, **kwargs) manila_features = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) self.enable_public_shares = manila_features.get( 'enable_public_shares', True) if not self.enable_public_shares: self.fields.pop('is_public') def handle(self, request, data): share_id = self.initial['share_id'] is_public = data['is_public'] if self.enable_public_shares else False try: share = manila.share_get(self.request, share_id) manila.share_update( request, share, data['name'], data['description'], is_public=is_public) message = _('Updating share "%s"') % data['name'] messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:shares:index") exceptions.handle(request, _('Unable to update share.'), redirect=redirect) class UpdateMetadataForm(forms.SelfHandlingForm): metadata = forms.CharField(widget=forms.Textarea, label=_("Metadata"), required=False) def __init__(self, *args, **kwargs): super(UpdateMetadataForm, self).__init__(*args, **kwargs) meta_str = "" for k, v in self.initial["metadata"].items(): meta_str += "%s=%s\r\n" % (k, v) self.initial["metadata"] = meta_str def handle(self, request, data): share_id = self.initial['share_id'] try: share = manila.share_get(self.request, share_id) set_dict, unset_list = utils.parse_str_meta(data['metadata']) if set_dict: manila.share_set_metadata(request, share, set_dict) if unset_list: manila.share_delete_metadata(request, share, unset_list) message = _('Updating share metadata "%s"') % share.name messages.success(request, message) return True except ValidationError as e: self.api_error(e.messages[0]) return False except Exception: redirect = reverse("horizon:project:shares:index") exceptions.handle(request, _('Unable to update share metadata.'), redirect=redirect) class AddRule(forms.SelfHandlingForm): access_type = forms.ChoiceField( label=_("Access Type"), required=True, choices=(('ip', 'ip'), ('user', 'user'), ('cert', 'cert'), ('cephx', 'cephx'))) access_level = forms.ChoiceField( label=_("Access Level"), required=True, choices=(('rw', 'read-write'), ('ro', 'read-only'),)) access_to = forms.CharField( label=_("Access To"), max_length="255", required=True) metadata = forms.CharField( label=_("Metadata"), required=False, widget=forms.Textarea(attrs={'rows': 4})) def handle(self, request, data): share_id = self.initial['share_id'] metadata = {} try: set_dict, unset_list = utils.parse_str_meta(data['metadata']) if unset_list: msg = _("Expected only pairs of key=value.") raise ValidationError(message=msg) metadata = set_dict except ValidationError as e: self.api_error(e.messages[0]) return False try: manila.share_allow( request, share_id, access_to=data['access_to'], access_type=data['access_type'], access_level=data['access_level'], metadata=metadata) message = _('Creating rule for "%s"') % data['access_to'] messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:shares:manage_rules", args=[self.initial['share_id']]) exceptions.handle( request, _('Unable to add rule.'), redirect=redirect) class UpdateRuleMetadataForm(forms.SelfHandlingForm): metadata = forms.CharField(widget=forms.Textarea, label=_("Metadata"), required=False) def __init__(self, *args, **kwargs): super(UpdateRuleMetadataForm, self).__init__(*args, **kwargs) rule_metadata = utils.metadata_to_str( self.initial["metadata"] ).replace('
', '\r\n') self.initial["metadata"] = rule_metadata def handle(self, request, data): rule_id = self.initial['rule_id'] try: rule = manila.share_rule_get(self.request, rule_id) set_dict, unset_list = utils.parse_str_meta(data['metadata']) if set_dict: manila.share_rule_set_metadata(request, rule, set_dict) if unset_list: manila.share_rule_unset_metadata(request, rule, unset_list) message = _('Updating share access rule metadata ') messages.success(request, message) return True except ValidationError as e: self.api_error(e.messages[0]) return False except Exception: redirect = reverse("horizon:project:shares:manage_rules", args=[self.initial['share_id']]) exceptions.handle(request, _('Unable to update rule metadata.'), redirect=redirect) class ResizeForm(forms.SelfHandlingForm): name = forms.CharField( max_length="255", label=_("Share Name"), widget=forms.TextInput(attrs={'readonly': 'readonly'}), required=False, ) orig_size = forms.IntegerField( label=_("Current Size (GiB)"), widget=forms.TextInput(attrs={'readonly': 'readonly'}), required=False, ) new_size = forms.IntegerField( label=_("New Size (GiB)") ) def clean(self): cleaned_data = super(ResizeForm, self).clean() new_size = cleaned_data.get('new_size') orig_size = self.initial['orig_size'] if new_size == orig_size: message = _("New size must be different than the existing size") self._errors["new_size"] = self.error_class([message]) return cleaned_data if new_size <= 0: message = _("New size should not be less than or equal to zero") self._errors["new_size"] = self.error_class([message]) return cleaned_data usages = manila.tenant_absolute_limits(self.request) availableGB = (usages['maxTotalShareGigabytes'] - usages['totalShareGigabytesUsed']) if availableGB < (new_size - orig_size): message = _('Share cannot be extended to %(req)iGiB as ' 'you only have %(avail)iGiB of your quota ' 'available.') params = {'req': new_size, 'avail': availableGB + orig_size} self._errors["new_size"] = self.error_class([message % params]) return cleaned_data def handle(self, request, data): share_id = self.initial['share_id'] new_size = data['new_size'] orig_size = data['orig_size'] try: manila.share_resize(request, share_id, new_size, orig_size) return self.check_size(request, share_id, new_size) except Exception: redirect = reverse("horizon:project:shares:index") exceptions.handle(request, _( 'Unable to resize share.'), redirect=redirect) def check_size(self, request, share_id, new_size): share = manila.share_get(request, share_id) timeout = 30 interval = 0.35 time_elapsed = 0 while share.status != 'available': time.sleep(interval) time_elapsed += interval share = manila.share_get(request, share_id) if time_elapsed > timeout: raise exceptions.WorkflowError(_( "The operation timed out while resizing. " "Please try again.")) if share.size == new_size: message = _('Resized share "%s"') % share.name messages.success(request, message) return True raise exceptions.WorkflowError(_( "Unable to resize share. ")) class RevertForm(forms.SelfHandlingForm): """Form for reverting a share to a snapshot.""" snapshot = forms.ChoiceField( label=_("Snapshot"), required=True, widget=forms.Select( attrs={'class': 'switchable', 'data-slug': 'share_snapshot'})) def __init__(self, req, *args, **kwargs): super(self.__class__, self).__init__(req, *args, **kwargs) # NOTE(vponomaryov): manila client does not allow to filter snapshots # using "created_at" field, so, we need to get all snapshots of a share # and do filtering here. search_opts = {'share_id': self.initial['share_id']} snapshots = manila.share_snapshot_list(req, search_opts=search_opts) amount_of_snapshots = len(snapshots) if amount_of_snapshots < 1: self.fields['snapshot'].choices = [("", "")] else: snapshot = snapshots[0] if amount_of_snapshots > 1: for s in snapshots[1:]: if s.created_at > snapshot.created_at: snapshot = s self.fields['snapshot'].choices = [ (snapshot.id, snapshot.name or snapshot.id)] def handle(self, request, data): share_id = self.initial['share_id'] snapshot_id = data['snapshot'] try: manila.share_revert(request, share_id, snapshot_id) message = _('Share "%(s)s" has been reverted to "%(ss)s" snapshot ' 'successfully') % {'s': share_id, 'ss': snapshot_id} messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:shares:index") exceptions.handle( request, _('Unable to revert share to the snapshot.'), redirect=redirect) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/panel.py0000664000175000017500000000161500000000000024147 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class Shares(horizon.Panel): name = _("Shares") slug = 'shares' permissions = ( 'openstack.services.share', ) dashboard.Project.register(Shares) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8226514 manila-ui-11.0.0/manila_ui/dashboards/project/shares/replicas/0000775000175000017500000000000000000000000024275 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/replicas/__init__.py0000664000175000017500000000000000000000000026374 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/replicas/forms.py0000664000175000017500000000555400000000000026006 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import messages from manila_ui.api import manila class CreateReplicaForm(forms.SelfHandlingForm): availability_zone = forms.ChoiceField( label=_("Availability Zone"), required=False) def __init__(self, request, *args, **kwargs): super(CreateReplicaForm, self).__init__(request, *args, **kwargs) # populate share_id share_id = kwargs.get('initial', {}).get('share_id', []) self.fields['share_id'] = forms.CharField(widget=forms.HiddenInput(), initial=share_id) availability_zones = manila.availability_zone_list(request) self.fields['availability_zone'].choices = ( [(az.name, az.name) for az in availability_zones]) def handle(self, request, data): try: replica = manila.share_replica_create(request, data['share_id'], data['availability_zone']) message = _('Creating replica for share "%s".') % data['share_id'] messages.success(request, message) return replica except Exception: redirect = reverse("horizon:project:shares:manage_replicas", args=[data['share_id']]) exceptions.handle(request, _('Unable to create share replica.'), redirect=redirect) class SetReplicaAsActiveForm(forms.SelfHandlingForm): def handle(self, request, data): replica_id = self.initial['replica_id'] try: replica = manila.share_replica_get(self.request, replica_id) manila.share_replica_promote(request, replica) message = _('Setting replica "%s" as active...') % replica_id messages.success(request, message) return True except Exception: redirect = reverse("horizon:project:shares:index") exceptions.handle( request, _("Unable to set replica '%s' as active.") % replica_id, redirect=redirect) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/replicas/tables.py0000775000175000017500000001406600000000000026133 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from django.template.defaultfilters import title from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import messages from horizon import tables from horizon.utils import filters from manila_ui.api import manila DELETABLE_STATUSES = ("error", "available") class UpdateReplicaRow(tables.Row): ajax = True def get_data(self, request, replica_id): replica = manila.share_replica_get(request, replica_id) return replica class CreateReplica(tables.LinkAction): name = "replicas" verbose_name = _("Create Replica") url = "horizon:project:shares:create_replica" classes = ("ajax-modal", "btn-camera") icon = "plus" policy_rules = (("share", "share:create_replica"),) def allowed(self, request, datum=None): share = manila.share_get(request, self.table.kwargs['share_id']) return share.replication_type is not None def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def get_link_url(self): return reverse(self.url, args=[self.table.kwargs['share_id']]) class SetReplicaAsActive(tables.LinkAction): name = "set_replica_as_active" verbose_name = _("Set as Active") url = "horizon:project:shares:set_replica_as_active" classes = ("ajax-modal", "btn-create") policy_rules = (("share_replica", "share_replica:promote"),) def allowed(self, request, replica=None): return (replica.status == "available" and replica.replica_state == "in_sync") def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def get_link_url(self, replica): return reverse(self.url, args=(replica.id,)) class DeleteReplica(tables.DeleteAction): policy_rules = (("share_replica", "share_replica:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Replica", u"Delete Replicas", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Replica", u"Deleted Replicas", count ) def get_policy_target(self, request, datum=None): return {"project_id": getattr(datum, "project_id", None)} def delete(self, request, obj_id): try: manila.share_replica_delete(request, obj_id) except Exception: msg = _('Unable to delete replica "%s".') % obj_id messages.error(request, msg) def allowed(self, request, replica=None): if replica: share = manila.share_get(request, replica.share_id) replicas = manila.share_replica_list(request, replica.share_id) if share.replication_type is None: return False elif (share.replication_type == 'writable' and replica.status in DELETABLE_STATUSES and len(replicas) > 1) or ( share.replication_type in ('dr', 'readable') and replica.status in DELETABLE_STATUSES and replica.replica_state != 'active'): return True return False def single(self, data_table, request, object_id): try: manila.share_replica_delete(request, object_id) messages.success( request, _('Share replica %s has been deleted.') % object_id) except Exception: msg = _('Unable to delete replica "%s".') % object_id messages.error(request, msg) _DETAIL_URL = "horizon:project:shares:replica_detail" class ReplicasTable(tables.DataTable): STATUS_CHOICES = ( ("creating", None), ("available", True), ("error", False), ("deleting", None), ) STATUS_DISPLAY_CHOICES = ( ("available", pgettext_lazy("Current status of replica", u"Available")), ("creating", pgettext_lazy("Current status of replica", u"Creating")), ("deleting", pgettext_lazy("Current status of replica", u"Deleting")), ("error", pgettext_lazy("Current status of replica", u"Error")), ) id = tables.Column( "id", verbose_name=_("ID"), link=_DETAIL_URL, ) availability_zone = tables.Column( "availability_zone", verbose_name=_("Availability zone")) status = tables.Column( "status", filters=(title,), verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES, ) replica_state = tables.Column( "replica_state", verbose_name=_("Replica State")) created_at = tables.Column( "created_at", verbose_name=_("Created At"), filters=(filters.parse_isotime,)) updated_at = tables.Column( "updated_at", verbose_name=_("Updated At"), filters=(filters.parse_isotime,)) def get_object_display(self, obj): return obj.id def get_object_id(self, obj): return str(obj.id) class Meta(object): name = "replicas" verbose_name = _("Replicas") status_columns = ("status",) row_class = UpdateReplicaRow table_actions = ( CreateReplica, ) row_actions = ( SetReplicaAsActive, DeleteReplica) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/replicas/tabs.py0000664000175000017500000000206300000000000025601 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from django.utils.translation import gettext_lazy as _ from horizon import tabs class ReplicaOverviewTab(tabs.Tab): name = _("Overview") slug = "overview" template_name = "project/shares/replicas/_detail_overview.html" def get_context_data(self, request): return {"replica": self.tab_group.kwargs['replica']} class ReplicaDetailTabs(tabs.TabGroup): slug = "replica_details" tabs = (ReplicaOverviewTab,) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/replicas/views.py0000664000175000017500000001551600000000000026014 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.project.shares.replicas import ( forms as replicas_forms) from manila_ui.dashboards.project.shares.replicas import ( tables as replicas_tables) from manila_ui.dashboards.project.shares.replicas import tabs as replicas_tabs from manila_ui.dashboards import utils as ui_utils class ManageReplicasView(tables.DataTableView): table_class = replicas_tables.ReplicasTable template_name = 'project/shares/replicas/manage_replicas.html' _redirect_url = 'horizon:project:shares:index' def get_context_data(self, **kwargs): context = super(ManageReplicasView, self).get_context_data(**kwargs) try: share = manila.share_get(self.request, self.kwargs["share_id"]) except Exception: redirect = reverse(self._redirect_url) exceptions.handle( self.request, _('Unable to retrieve share. %s') % self.kwargs["share_id"], redirect=redirect) context["share_display_name"] = share.name or share.id context["share"] = self.get_data() context["page_title"] = _( "Share Replicas: %(share_display_name)s") % { "share_display_name": context["share_display_name"]} return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] return manila.share_replica_list(self.request, share_id) except Exception: redirect = reverse(self._redirect_url) exceptions.handle( self.request, _('Unable to retrieve share replicas.'), redirect=redirect) class DetailReplicaView(tabs.TabView): tab_group_class = replicas_tabs.ReplicaDetailTabs template_name = 'project/shares/replicas/detail.html' _redirect_url = 'horizon:project:shares:index' def get_context_data(self, **kwargs): context = super(DetailReplicaView, self).get_context_data(**kwargs) replica = self.get_data() replica_display_name = replica.id context["replica"] = replica context["replica_display_name"] = replica_display_name context["page_title"] = _( "Replica Details: %(replica_display_name)s") % { "replica_display_name": replica_display_name} return context @memoized.memoized_method def get_data(self): try: replica_id = self.kwargs['replica_id'] replica = manila.share_replica_get(self.request, replica_id) try: # The default policy for this API does not allow # non-admins to retrieve export locations. replica.export_locations = ( manila.share_instance_export_location_list( self.request, replica_id)) export_locations = [ exp['path'] for exp in replica.export_locations ] replica.el_size = ui_utils.calculate_longest_str_size( export_locations) except Exception: replica.export_locations = [] except Exception: redirect = reverse(self._redirect_url) exceptions.handle( self.request, _('Unable to retrieve details of replica %s') % self.kwargs['replica_id'], redirect=redirect) return replica def get_tabs(self, request, *args, **kwargs): replica = self.get_data() return self.tab_group_class(request, replica=replica, **kwargs) class CreateReplicaView(forms.ModalFormView): form_class = replicas_forms.CreateReplicaForm form_id = "create_replica" template_name = 'project/shares/replicas/create_replica.html' modal_header = _("Create Replica") modal_id = "create_replica_modal" submit_label = _("Create") submit_url = "horizon:project:shares:create_replica" success_url = 'horizon:project:shares:manage_replicas' page_title = _("Create Replica") def get_context_data(self, **kwargs): context = super(CreateReplicaView, self).get_context_data(**kwargs) context['share_id'] = self.kwargs['share_id'] args = (context['share_id'],) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): return {'share_id': self.kwargs["share_id"]} def get_success_url(self): return reverse(self.success_url, args=[self.kwargs['share_id']]) class SetReplicaAsActiveView(forms.ModalFormView): form_class = replicas_forms.SetReplicaAsActiveForm form_id = "set_replica_as_active" template_name = "project/shares/replicas/set_replica_as_active.html" modal_header = _("Set Replica as Active") modal_id = "set_replica_as_active_modal" submit_label = _("Set as Active") submit_url = "horizon:project:shares:set_replica_as_active" success_url = "horizon:project:shares:manage_replicas" page_title = _("Set Replica as Active") def get_success_url(self): return reverse(self.success_url, args=[self.get_object().share_id]) def get_object(self): if not hasattr(self, "_object"): replica_id = self.kwargs["replica_id"] try: self._object = manila.share_replica_get( self.request, replica_id) except Exception: msg = _("Unable to retrieve replica '%s'.") % replica_id url = reverse("horizon:project:shares:index") exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(SetReplicaAsActiveView, self).get_context_data( **kwargs) context["replica_id"] = self.kwargs["replica_id"] args = (context["replica_id"],) context["submit_url"] = reverse(self.submit_url, args=args) return context def get_initial(self): return {"replica_id": self.kwargs["replica_id"]} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/tables.py0000664000175000017500000003702700000000000024330 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.template.defaultfilters import title from django.urls import reverse from django.utils.text import format_lazy from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from django.utils.translation import pgettext_lazy from horizon import exceptions from horizon import messages from horizon import tables from horizon.utils import filters from manila_ui.api import manila from manila_ui.dashboards.project.share_snapshots import tables as ss_tables from manila_ui.dashboards import utils from manila_ui import features DELETABLE_STATES = ( "AVAILABLE", "ERROR", "MANAGE_ERROR", ) class DeleteShare(tables.DeleteAction): policy_rules = (("share", "share:delete"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Share", u"Delete Shares", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Share", u"Deleted Shares", count ) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} def delete(self, request, obj_id): share = manila.share_get(request, obj_id) try: manila.share_delete( request, share.id, share_group_id=share.share_group_id) except Exception: msg = _('Unable to delete share "%s". ') % obj_id messages.error(request, msg) def allowed(self, request, share=None): if share: # Row button return (share.status.upper() in DELETABLE_STATES and not getattr(share, 'has_snapshot', False)) # Table button. Always return 'True'. return True class CreateShare(tables.LinkAction): name = "create" verbose_name = _("Create Share") url = "horizon:project:shares:create" classes = ("ajax-modal", "btn-create") icon = "plus" policy_rules = (("share", "share:create"),) def allowed(self, request, share=None): usages = manila.tenant_absolute_limits(request) shares_allowed = (usages['maxTotalShares'] > usages['totalSharesUsed'] and usages['maxTotalShareGigabytes'] > usages['totalShareGigabytesUsed']) if not shares_allowed: if "disabled" not in self.classes: self.classes = [c for c in self.classes] + ['disabled'] self.verbose_name = format_lazy( '{verbose_name} {quota_exceeded}', verbose_name=self.verbose_name, quota_exceeded=_("(Quota exceeded)")) else: self.verbose_name = _("Create Share") classes = [c for c in self.classes if c != "disabled"] self.classes = classes return True class EditShare(tables.LinkAction): name = "edit" verbose_name = _("Edit Share") url = "horizon:project:shares:update" classes = ("ajax-modal", "btn-create") policy_rules = (("share", "share:update"),) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} def allowed(self, request, share=None): return share.status in ("available", "in-use") class EditShareMetadata(tables.LinkAction): name = "update_metadata" verbose_name = _("Edit Share Metadata") url = "horizon:project:shares:update_metadata" classes = ("ajax-modal", "btn-create") policy_rules = (("share", "share:update_share_metadata"),) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} def allowed(self, request, share=None): return share.status in ("available", "in-use") class ResizeShare(tables.LinkAction): name = "resize_share" verbose_name = _("Resize Share") url = "horizon:project:shares:resize" classes = ("ajax-modal", "btn-create") policy_rules = (("share", "share:resize"),) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} def allowed(self, request, share=None): return share.status.lower() in ("available",) class RevertShare(tables.LinkAction): name = "revert_share" verbose_name = _("Revert Share") url = "horizon:project:shares:revert" classes = ("ajax-modal", "btn-create") policy_rules = (("share", "share:revert"),) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} def allowed(self, request, share=None): return ( getattr(share, 'revert_to_snapshot_support', False) and share.status.lower() == "available" ) class UpdateRow(tables.Row): ajax = True def get_data(self, request, share_id): share = manila.share_get(request, share_id) if not share.name: share.name = share_id if share.share_network_id: share_net = manila.share_network_get(request, share.share_network_id) share.share_network = share_net.name or share_net.id else: share.share_network = None share.metadata = utils.metadata_to_str(share.metadata) return share def get_size(share): return _("%sGiB") % share.size class SharesTableBase(tables.DataTable): STATUS_CHOICES = ( ("available", True), ("AVAILABLE", True), ("creating", None), ("CREATING", None), ("deleting", None), ("DELETING", None), ("reverting", None), ("migrating", None), ("migrating_to", None), ("error", False), ("ERROR", False), ("error_deleting", False), ("ERROR_DELETING", False), ("MANAGE_ERROR", False), ("UNMANAGE_ERROR", False), ("extending_error", False), ("shrinking_error", False), ("shrinking_possible_data_loss_error", False), ("reverting_error", False), ) STATUS_DISPLAY_CHOICES = ( ("available", pgettext_lazy("Current status of share", u"Available")), ("AVAILABLE", pgettext_lazy("Current status of share", u"Available")), ("creating", pgettext_lazy("Current status of share", u"Creating")), ("CREATING", pgettext_lazy("Current status of share", u"Creating")), ("deleting", pgettext_lazy("Current status of share", u"Deleting")), ("DELETING", pgettext_lazy("Current status of share", u"Deleting")), ("migrating", pgettext_lazy("Current status of share", u"Migrating")), ("migrating_to", pgettext_lazy("Current status of share", u"Migrating to")), ("error", pgettext_lazy("Current status of share", u"Error")), ("ERROR", pgettext_lazy("Current status of share", u"Error")), ("error_deleting", pgettext_lazy("Current status of share", u"Deleting")), ("ERROR_DELETING", pgettext_lazy("Current status of share", u"Deleting")), ("MANAGE_ERROR", pgettext_lazy("Current status of share", u"Manage Error")), ("UNMANAGE_ERROR", pgettext_lazy("Current status of share", u"Unmanage Error")), ("extending_error", pgettext_lazy("Current status of share", u"Extending Error")), ("shrinking_error", pgettext_lazy("Current status of share", u"Shrinking Error")), ("shrinking_possible_data_loss_error", pgettext_lazy( "Current status of share", u"Shrinking Error")), ("reverting_error", pgettext_lazy("Current status of share", u"Reverting Error")), ) name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:project:shares:detail") description = tables.Column("description", verbose_name=_("Description"), truncate=40) metadata = tables.Column("metadata", verbose_name=_("Metadata")) size = tables.Column(get_size, verbose_name=_("Size"), attrs={'data-type': 'size'}) status = tables.Column("status", filters=(title,), verbose_name=_("Status"), status=True, status_choices=STATUS_CHOICES, display_choices=STATUS_DISPLAY_CHOICES) def get_object_display(self, obj): return obj.name or obj.id def get_share_group_link(share): if (features.is_share_groups_enabled() and getattr(share, 'share_group_id', None)): return reverse( "horizon:project:share_groups:detail", args=(share.share_group_id,)) else: return None share_group_id = tables.Column( "share_group_id", verbose_name=_("Share Group"), empty_value="-", link=get_share_group_link, ) class ManageRules(tables.LinkAction): name = "manage_rules" verbose_name = _("Manage Rules") url = "horizon:project:shares:manage_rules" classes = ("btn-edit",) policy_rules = (("share", "share:access_get_all"),) class ManageReplicas(tables.LinkAction): name = "manage_replicas" verbose_name = _("Manage Replicas") url = "horizon:project:shares:manage_replicas" classes = ("btn-edit",) policy_rules = (("share", "share:replica_get_all"),) def allowed(self, request, share): share_replication_enabled = share.replication_type is not None return features.is_replication_enabled() and share_replication_enabled class AddRule(tables.LinkAction): name = "rule_add" verbose_name = _("Add rule") url = 'horizon:project:shares:rule_add' classes = ("ajax-modal", "btn-create") icon = "plus" policy_rules = (("share", "share:allow_access"),) def allowed(self, request, share=None): share = manila.share_get(request, self.table.kwargs['share_id']) return share.status in ("available", "in-use") def get_link_url(self): return reverse(self.url, args=[self.table.kwargs['share_id']]) class DeleteRule(tables.DeleteAction): policy_rules = (("share", "share:deny_access"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete Rule", u"Delete Rules", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted Rule", u"Deleted Rules", count ) def delete(self, request, obj_id): try: manila.share_deny(request, self.table.kwargs['share_id'], obj_id) except Exception: msg = _('Unable to delete rule "%s".') % obj_id exceptions.handle(request, msg) class EditRuleMetadata(tables.LinkAction): name = "update_rule_metadata" verbose_name = _("Edit Rule Metadata") url = "horizon:project:shares:update_rule_metadata" classes = ("ajax-modal", "btn-create") policy_rules = (("share_access_metadata", "share_access_metadata:update"),) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "os-share-tenant-attr:tenant_id", None) return {"project_id": project_id} def allowed(self, request, rule=None): return rule.state == "active" class UpdateRuleRow(tables.Row): ajax = True def get_data(self, request, rule_id): rule = manila.share_rule_get(request, rule_id) rule.metadata = utils.metadata_to_str(rule.metadata) return rule class RulesTable(tables.DataTable): access_type = tables.Column("access_type", verbose_name=_("Access Type")) access_to = tables.Column("access_to", verbose_name=_("Access to")) access_level = tables.Column( "access_level", verbose_name=_("Access Level")) metadata = tables.Column( "metadata", verbose_name=_("Metadata")) status = tables.Column("state", verbose_name=_("Status")) access_key = tables.Column("access_key", verbose_name=_("Access Key")) created_at = tables.Column("created_at", verbose_name=_("Created At"), filters=(filters.parse_isotime,)) updated_at = tables.Column("updated_at", verbose_name=_("Updated At"), filters=(filters.parse_isotime,)) def get_object_display(self, obj): return obj.id class Meta(object): name = "rules" verbose_name = _("Rules") status_columns = ["status"] row_class = UpdateRuleRow table_actions = ( AddRule, DeleteRule) row_actions = ( DeleteRule, EditRuleMetadata,) def get_share_network(share): name = share.share_network_name return name if name != "None" else None class SharesTable(SharesTableBase): name = tables.WrappingColumn( "name", verbose_name=_("Name"), link="horizon:project:shares:detail") visibility = tables.Column( "is_public", verbose_name=_("Visibility"), help_text=("Whether this share visible to all tenants (public) or " "only for owner (private)."), filters=(lambda d: 'public' if d is True else 'private', ), ) proto = tables.Column("share_proto", verbose_name=_("Protocol")) share_network = tables.Column("share_network", verbose_name=_("Share Network"), empty_value="-") class Meta(object): name = "shares" verbose_name = _("Shares") status_columns = ["status"] row_class = UpdateRow table_actions = ( tables.NameFilterAction, CreateShare, DeleteShare) row_actions = ( EditShare, ResizeShare, RevertShare, ss_tables.CreateShareSnapshot, ManageRules, ManageReplicas, EditShareMetadata, DeleteShare) columns = [ 'name', 'description', 'metadata', 'size', 'status', 'proto', 'visibility', 'share_network', ] if features.is_share_groups_enabled(): columns.append('share_group_id') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/tabs.py0000664000175000017500000000173300000000000024002 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class OverviewTab(tabs.Tab): name = _("Overview") slug = "overview" template_name = "project/shares/_detail.html" def get_context_data(self, request): return {"share": self.tab_group.kwargs['share']} class ShareDetailTabs(tabs.TabGroup): slug = "share_details" tabs = ( OverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/0000775000175000017500000000000000000000000024471 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8266513 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/0000775000175000017500000000000000000000000025756 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_create.html0000664000175000017500000000032600000000000030247 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}
{% include "project/shares/_limits.html" with usages=usages %}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_detail.html0000664000175000017500000000764200000000000030256 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Overview" %}


{% trans "Name" %}
{{ share.name }}
{% trans "ID" %}
{{ share.id }}
{% if share.description %}
{% trans "Description" %}
{{ share.description }}
{% endif %}
{% trans "Status" %}
{{ share.status|capfirst }}
{% trans "Export locations" %}
{% for el in share.export_locations %}

{% trans "Path:" %}
{% trans "Preferred:" %} {{ el.preferred }}
{% if el.is_admin_only == True or el.is_admin_only == False %}
{% trans "Is admin only:" %} {{ el.is_admin_only }}
{% endif %} {% if el.share_instance_id %}
{% trans "Share Replica ID:" %} {{ el.share_instance_id }}
{% endif %}

{% endfor %} {% if share.snapshot_id %}
{% trans "Snapshot ID" %}
{% url 'horizon:project:share_snapshots:share_snapshot_detail' share.snapshot_id as snapshot_url%}
{{ share.snapshot_id }}
{% endif %}
{% trans "Visibility" %}
{% if share.is_public == True %}
{{ 'public' }}
{% else %}
{{ 'private' }}
{% endif %}
{% trans "Availability zone" %}
{{ share.availability_zone }}
{% trans "Size" %}
{{ share.size }} {% trans "GiB" %}
{% trans "Protocol" %}
{{ share.share_proto }}
{% if share.share_type %}
{% trans "Share type" %}

{% trans "Name:" %} {{ share.share_type_name }}
{% trans "ID:" %} {{ share.share_type }}

{% endif %} {% if share.share_network_id %}
{% trans "Share Network" %}
{% url 'horizon:project:share_networks:share_network_detail' share.share_network_id as sn_url%}
{{ share.share_network_id }}
{% endif %} {% if share.share_group_id %}
{% trans "Share Group" %}
{% url 'horizon:project:share_groups:detail' share.share_group_id as sg_url%}
{{ share.share_group_id }}
{% endif %}
{% trans "Mount snapshot support" %}
{{ share.mount_snapshot_support }}
{% trans "Created" %}
{{ share.created_at|parse_date }}
{% if share.host %}
{% trans "Host" %}
{{ share.host }}
{% endif %}
{% trans "Task state" %}
{{ share.task_state }}

{% trans "Access Rules" %}


{% for rule in share.rules %}
{{ rule.access_type }}

{% trans "Access to:" %} {{ rule.access_to }}
{% trans "Access Level:" %} {{ rule.access_level }}
{% trans "Status:" %} {{ rule.state }}
{% trans "Access Key:" %} {{ rule.access_key }}
{% trans "Created At:" %} {{ rule.created_at|parse_date }}
{% trans "Updated At:" %} {{ rule.updated_at|parse_date }}

{% endfor %}

{% trans "Metadata" %}


{% for key, value in share.metadata.items %}
{{ key }}
{{ value }}
{% endfor %}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_limits.html0000664000175000017500000000445700000000000030316 0ustar00zuulzuul00000000000000{% load i18n horizon humanize bootstrap %}

{% trans "Description" %}:

{% trans "Select parameters of share you want to create. " %}

{% trans "Metadata" %}:

{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add metadata use:" %}

key=value

{% trans "Share Limits" %}

{% trans "Total Gibibytes" %}
{% blocktrans with used=usages.totalShareGigabytesUsed|intcomma quota=usages.maxTotalShareGigabytes|intcomma|quotainf %}{{ used }} of {{ quota }} GiB Used{% endblocktrans %}
{{ minifyspace }}
{% widthratio usages.totalShareGigabytesUsed usages.maxTotalShareGigabytes 100 as gigabytes_percent %} {% bs_progress_bar gigabytes_percent 0 %}
{{ endminifyspace }}
{% block type_title %}{% trans "Number of Shares" %}{% endblock %}
{% block used_of_quota %} {% blocktrans with used=usages.totalSharesUsed|intcomma quota=usages.maxTotalShares|intcomma|quotainf %}{{ used }} of {{ quota }} Used{% endblocktrans %} {% endblock %}
{{ minifyspace }}
{% block show_progress_bar %} {% widthratio usages.totalSharesUsed usages.maxTotalShares 100 as shares_percent %} {% widthratio 100 usages.maxTotalShares 1 as single_step %} {% bs_progress_bar shares_percent single_step %} {% endblock %}
{{ endminifyspace }} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_manage_rules.html0000664000175000017500000000010000000000000031434 0ustar00zuulzuul00000000000000
{{ manage_rules_table.render }}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_resize.html0000664000175000017500000000033500000000000030305 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}
{% include "project/shares/_resize_limits.html" with usages=usages %}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_resize_limits.html0000664000175000017500000000203400000000000031664 0ustar00zuulzuul00000000000000{% load i18n horizon humanize bootstrap %}

{% trans "Description" %}:

{% trans "Resize the size of a share. " %}

{% trans "Share Limits" %}

{% trans "Total Gibibytes" %} ({{ usages.totalShareGigabytesUsed|intcomma }} {% trans "GiB" %})
{{ usages.maxTotalShareGigabytes|intcomma|quota:_("GiB") }}
{% widthratio usages.totalShareGigabytesUsed usages.maxTotalShareGigabytes 100 as gigabytes_percent %} {% bs_progress_bar gigabytes_percent 0 %}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_revert.html0000664000175000017500000000035000000000000030310 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can revert the share to its latest snapshot." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_rule_add.html0000664000175000017500000000056700000000000030572 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% blocktrans trimmed %} Add policy rule to share, 'ip' rule represents IPv4 or IPv6 address, 'user' rule represents username or usergroup, 'cephx' rule represents ceph auth ID. {% endblocktrans %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_update.html0000664000175000017500000000036300000000000030267 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "From here you can modify name, description and visibility of a share." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_update_metadata.html0000664000175000017500000000071000000000000032123 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Metadata" %}:

{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add metadata use:" %}

key=value
{% trans "To unset metadata use:" %}
key
{% trans "All pairs that are in field for left are set for this metadata." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/_update_rule_metadata.html0000664000175000017500000000071000000000000033152 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Metadata" %}:

{% trans "One line - one action. Empty strings will be ignored." %}
{% trans "To add metadata use:" %}

key=value
{% trans "To unset metadata use:" %}
key
{% trans "All pairs that are in field for left are set for this metadata." %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/create.html0000664000175000017500000000026500000000000030112 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share" %}{% endblock %} {% block main %} {% include 'project/shares/_create.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/detail.html0000664000175000017500000000033300000000000030105 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/index.html0000664000175000017500000000033100000000000027750 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Shares" %}{% endblock %} {% block main %}
{{ shares_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/manage_rules.html0000664000175000017500000000023100000000000031302 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Rules" %}{% endblock %} {% block main %} {{ table.render }} {% endblock %} ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8266513 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/0000775000175000017500000000000000000000000027560 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/_create_replica.html0000664000175000017500000000033100000000000033544 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body-right %}

{% trans "Description" %}:

{% trans "Create share replica in specific availability zone." %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/_detail_overview.html0000664000175000017500000000314200000000000033775 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "Share Replica Overview" %}


{% trans "ID" %}
{{ replica.id }}
{% trans "Share" %}
{% url 'horizon:project:shares:detail' replica.share_id as share_url%}
{{ replica.share_id }}
{% trans "Status" %}
{{ replica.status|capfirst }}
{% trans "Replica state" %}
{{ replica.replica_state|capfirst }}
{% if replica.export_locations %}
{% trans "Export locations" %}
{% for el in replica.export_locations %}

Path:
Preferred: {{ el.preferred }}
{% if el.is_admin_only == True or el.is_admin_only == False %}
Is admin only: {{ el.is_admin_only }}
{% endif %}

{% endfor %} {% endif %}
{% trans "Availability zone" %}
{{ replica.availability_zone }}
{% trans "Created" %}
{{ replica.created_at|parse_date }}
{% trans "Updated" %}
{{ replica.updated_at|parse_date }}
{% if replica.host %}
{% trans "Host" %}
{{ replica.host }}
{% endif %}
././@PaxHeader0000000000000000000000000000021200000000000011450 xustar0000000000000000116 path=manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/_set_replica_as_active.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/_set_replica_as_activ0000664000175000017500000000033100000000000034002 0ustar00zuulzuul00000000000000{% extends "horizon/common/_modal_form.html" %} {% load i18n %} {% block modal-body %}

{% trans "Set share replica with ID" %} "{{ replica_id }}" {% trans "as Active?" %}

{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/create_replica.html0000664000175000017500000000031500000000000033407 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Create Share Replica" %}{% endblock %} {% block main %} {% include 'project/shares/replicas/_create_replica.html' %} {% endblock %}././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/detail.html0000664000175000017500000000033500000000000031711 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Replica Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/manage_replicas.html0000664000175000017500000000023400000000000033557 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Share Replicas" %}{% endblock %} {% block main %} {{ table.render }} {% endblock %} ././@PaxHeader0000000000000000000000000000021100000000000011447 xustar0000000000000000115 path=manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/set_replica_as_active.html 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/replicas/set_replica_as_active0000664000175000017500000000032600000000000034014 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Set Replica as Active" %}{% endblock %} {% block main %} {% include 'project/shares/replicas/_set_replica_as_active.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/resize.html0000664000175000017500000000026500000000000030150 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Resize Share" %}{% endblock %} {% block main %} {% include 'project/shares/_resize.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/revert.html0000664000175000017500000000026500000000000030156 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Revert Share" %}{% endblock %} {% block main %} {% include 'project/shares/_revert.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/rule_add.html0000664000175000017500000000026300000000000030424 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Add Rule" %}{% endblock %} {% block main %} {% include 'project/shares/_rule_add.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/update.html0000664000175000017500000000026300000000000030127 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Edit Share" %}{% endblock %} {% block main %} {% include 'project/shares/_update.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/update_metadata.html0000664000175000017500000000030500000000000031764 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Edit Share Metadata" %}{% endblock %} {% block main %} {% include 'project/shares/_update_metadata.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/templates/shares/update_rule_metadata.html0000664000175000017500000000031100000000000033010 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Edit Rule Metadata" %}{% endblock %} {% block main %} {% include 'project/shares/_update_rule_metadata.html' %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/urls.py0000664000175000017500000000541300000000000024035 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.project.shares.replicas import views as replica_views from manila_ui.dashboards.project.shares import views as shares_views from manila_ui import features urlpatterns = [ re_path( r'^$', shares_views.SharesView.as_view(), name='index'), re_path( r'^create/$', shares_views.CreateView.as_view(), name='create'), re_path( r'^(?P[^/]+)/rules/$', shares_views.ManageRulesView.as_view(), name='manage_rules'), re_path( r'^(?P[^/]+)/rule_add/$', shares_views.AddRuleView.as_view(), name='rule_add'), re_path( r'^rules/(?P[^/]+)/update_rule_metadata/$', shares_views.UpdateRuleMetadataView.as_view(), name='update_rule_metadata'), re_path( r'^(?P[^/]+)/$', shares_views.DetailView.as_view(), name='detail'), re_path( r'^(?P[^/]+)/update/$', shares_views.UpdateView.as_view(), name='update'), re_path( r'^(?P[^/]+)/update_metadata/$', shares_views.UpdateMetadataView.as_view(), name='update_metadata'), re_path( r'^(?P[^/]+)/resize/$', shares_views.ResizeView.as_view(), name='resize'), re_path( r'^(?P[^/]+)/revert/$', shares_views.RevertView.as_view(), name='revert'), ] if features.is_replication_enabled(): urlpatterns.extend([ re_path( r'^(?P[^/]+)/create_replica/$', replica_views.CreateReplicaView.as_view(), name='create_replica'), re_path( r'^(?P[^/]+)/replicas/$', replica_views.ManageReplicasView.as_view(), name='manage_replicas'), re_path( r'^replica/(?P[^/]+)$', replica_views.DetailReplicaView.as_view(), name='replica_detail'), re_path( r'^replica/(?P[^/]+)/set_replica_as_active$', replica_views.SetReplicaAsActiveView.as_view(), name='set_replica_as_active'), ]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/shares/views.py0000664000175000017500000003641400000000000024212 0ustar00zuulzuul00000000000000# Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import forms from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.project.shares import forms as share_form from manila_ui.dashboards.project.shares import tables as shares_tables from manila_ui.dashboards.project.shares import tabs as shares_tabs from manila_ui.dashboards import utils as ui_utils class ShareTableMixIn(object): def _get_shares(self, search_opts=None): try: return manila.share_list(self.request, search_opts=search_opts) except Exception: exceptions.handle(self.request, _('Unable to retrieve share list.')) return [] def _set_id_if_nameless(self, shares): for share in shares: # It is possible to create a share with no name if not share.name: share.name = share.id class SharesView(tables.MultiTableView, ShareTableMixIn): table_classes = ( shares_tables.SharesTable, ) template_name = "project/shares/index.html" page_title = _("Shares") @memoized.memoized_method def get_shares_data(self): share_nets_names = {} share_nets = manila.share_network_list(self.request) for share_net in share_nets: share_nets_names[share_net.id] = share_net.name try: shares = manila.share_list(self.request) for share in shares: share.share_network = ( share_nets_names.get(share.share_network_id) or share.share_network_id) share.metadata = ui_utils.metadata_to_str(share.metadata) snapshots = manila.share_snapshot_list(self.request, detailed=True) share_ids_with_snapshots = [] for snapshot in snapshots: share_ids_with_snapshots.append(snapshot.to_dict()['share_id']) for share in shares: if share.to_dict()['id'] in share_ids_with_snapshots: setattr(share, 'has_snapshot', True) else: setattr(share, 'has_snapshot', False) except Exception: exceptions.handle( self.request, _('Unable to retrieve share list.')) return [] # Gather our tenants to correlate against IDs return shares class DetailView(tabs.TabView): tab_group_class = shares_tabs.ShareDetailTabs template_name = 'project/shares/detail.html' def get_context_data(self, **kwargs): context = super(DetailView, self).get_context_data(**kwargs) share = self.get_data() share_display_name = share.name or share.id context["share"] = share context["share_display_name"] = share_display_name context["page_title"] = _("Share Details: " "%(share_display_name)s") % { 'share_display_name': share_display_name} return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] share = manila.share_get(self.request, share_id) share.rules = manila.share_rules_list(self.request, share_id) share.export_locations = manila.share_export_location_list( self.request, share_id) export_locations = [ exp['path'] for exp in share.export_locations] share.el_size = ui_utils.calculate_longest_str_size( export_locations) except Exception: redirect = reverse('horizon:project:shares:index') exceptions.handle(self.request, _('Unable to retrieve share details.'), redirect=redirect) return share def get_tabs(self, request, *args, **kwargs): share = self.get_data() return self.tab_group_class(request, share=share, **kwargs) class CreateView(forms.ModalFormView): form_class = share_form.CreateForm form_id = "create_share" template_name = 'project/shares/create.html' modal_header = _("Create Share") modal_id = "create_share_modal" submit_label = _("Create") submit_url = reverse_lazy("horizon:project:shares:create") success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Create a Share') def get_context_data(self, **kwargs): context = super(CreateView, self).get_context_data(**kwargs) try: context['usages'] = manila.tenant_absolute_limits(self.request) except Exception: exceptions.handle(self.request) return context class UpdateView(forms.ModalFormView): form_class = share_form.UpdateForm form_id = "update_share" template_name = 'project/shares/update.html' modal_header = _("Edit Share") modal_id = "update_share_modal" submit_label = _("Edit") submit_url = "horizon:project:shares:update" success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Edit Share') def get_object(self): if not hasattr(self, "_object"): vol_id = self.kwargs['share_id'] try: self._object = manila.share_get(self.request, vol_id) except Exception: msg = _('Unable to retrieve share.') url = reverse('horizon:project:shares:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(UpdateView, self).get_context_data(**kwargs) return context def get_initial(self): self.submit_url = reverse(self.submit_url, kwargs=self.kwargs) share = self.get_object() return {'share_id': self.kwargs["share_id"], 'name': share.name, 'description': share.description, 'is_public': share.is_public} class UpdateMetadataView(forms.ModalFormView): form_class = share_form.UpdateMetadataForm form_id = "update_share_metadata" template_name = 'project/shares/update_metadata.html' modal_header = _("Edit Share Metadata") modal_id = "update_share_metadata_modal" submit_label = _("Save Changes") submit_url = "horizon:project:shares:update_metadata" success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Edit Share Metadata') def get_object(self): if not hasattr(self, "_object"): sh_id = self.kwargs['share_id'] try: self._object = manila.share_get(self.request, sh_id) except Exception: msg = _('Unable to retrieve share.') url = reverse('horizon:project:shares:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(UpdateMetadataView, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): share = self.get_object() return {'share_id': self.kwargs["share_id"], 'metadata': share.metadata} class AddRuleView(forms.ModalFormView): form_class = share_form.AddRule form_id = "rule_add" template_name = 'project/shares/rule_add.html' modal_header = _("Add Rule") modal_id = "rule_add_modal" submit_label = _("Add") submit_url = "horizon:project:shares:rule_add" success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Add Rule') def get_object(self): if not hasattr(self, "_object"): vol_id = self.kwargs['share_id'] try: self._object = manila.share_get(self.request, vol_id) except Exception: msg = _('Unable to retrieve share.') url = reverse('horizon:project:shares:index') exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(AddRuleView, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): share = self.get_object() return {'share_id': self.kwargs["share_id"], 'name': share.name, 'description': share.description} def get_success_url(self): return reverse("horizon:project:shares:manage_rules", args=[self.kwargs['share_id']]) class UpdateRuleMetadataView(forms.ModalFormView): form_class = share_form.UpdateRuleMetadataForm form_id = "" template_name = 'project/shares/update_rule_metadata.html' modal_header = _("Edit Rule Metadata") modal_id = "update_rule_metadata_modal" submit_label = _("Save Changes") submit_url = "horizon:project:shares:update_rule_metadata" success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Edit Rule Metadata') def get_object(self): if not hasattr(self, "_object"): rule_id = self.kwargs['rule_id'] try: self._object = manila.share_rule_get(self.request, rule_id) except Exception: msg = _('Unable to retrieve share access rule.') url = reverse('horizon:project:shares:manage_rules', args=[self.initial['share_id']]) exceptions.handle(self.request, msg, redirect=url) return self._object def get_context_data(self, **kwargs): context = super(UpdateRuleMetadataView, self).\ get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): rule = self.get_object() rule_id = self.kwargs["rule_id"] share_id = self.get_share_id(rule_id) return {'rule_id': rule_id, 'metadata': rule.metadata, 'share_id': share_id} def get_success_url(self): rule_id = self.kwargs["rule_id"] share_id = self.get_share_id(rule_id) return reverse("horizon:project:shares:manage_rules", args=[share_id]) # To redirect to Rules Table page, after updating the rule # metadata. Loop is to get the share_id neccessary to display # Rules Table page. def get_share_id(self, rule_id): shares = manila.share_list(self.request) for share in shares: rules = manila.share_rules_list(self.request, share.id) for rule in rules: if rule.id == rule_id: return share.id class ManageRulesView(tables.DataTableView): table_class = shares_tables.RulesTable template_name = 'project/shares/manage_rules.html' def get_context_data(self, **kwargs): context = super(ManageRulesView, self).get_context_data(**kwargs) share = manila.share_get(self.request, self.kwargs['share_id']) context['share_display_name'] = share.name or share.id context["page_title"] = _("Share Rules: " "%(share_display_name)s") % { 'share_display_name': context['share_display_name']} return context @memoized.memoized_method def get_data(self): try: share_id = self.kwargs['share_id'] rules = manila.share_rules_list(self.request, share_id) except Exception: redirect = reverse('horizon:project:shares:index') exceptions.handle(self.request, _('Unable to retrieve share rules.'), redirect=redirect) return [] for rule in rules: rule.metadata = ui_utils.metadata_to_str(rule.metadata) return rules class ResizeView(forms.ModalFormView): form_class = share_form.ResizeForm form_id = "resize_share" template_name = 'project/shares/resize.html' modal_header = _("Resize Share") modal_id = "resize_share_modal" submit_label = _("Resize") submit_url = "horizon:project:shares:resize" success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Resize Share') @memoized.memoized_method def get_object(self): try: return manila.share_get(self.request, self.kwargs['share_id']) except Exception: exceptions.handle(self.request, _('Unable to retrieve share.')) def get_context_data(self, **kwargs): context = super(ResizeView, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) try: context['usages'] = manila.tenant_absolute_limits(self.request) context['usages']['totalShareGigabytesUsed'] -= int( self.get_object().size) except Exception: exceptions.handle(self.request) return context def get_initial(self): share = self.get_object() if not share or isinstance(share, Exception): raise exceptions.NotFound() return { 'share_id': self.kwargs["share_id"], 'name': share.name or share.id, 'orig_size': share.size, 'new_size': int(share.size), } class RevertView(forms.ModalFormView): form_class = share_form.RevertForm form_id = "revert_share" template_name = 'project/shares/revert.html' modal_header = _("Revert Share to a Snapshot") modal_id = "revert_share_modal" submit_label = _("Revert share to a snapshot") submit_url = "horizon:project:shares:revert" success_url = reverse_lazy("horizon:project:shares:index") page_title = _('Revert Share to a Snapshot') @memoized.memoized_method def get_object(self): try: return manila.share_get(self.request, self.kwargs['share_id']) except Exception: exceptions.handle(self.request, _('Unable to retrieve share.')) def get_context_data(self, **kwargs): context = super(self.__class__, self).get_context_data(**kwargs) args = (self.get_object().id,) context['submit_url'] = reverse(self.submit_url, args=args) return context def get_initial(self): share = self.get_object() if not share or isinstance(share, Exception): raise exceptions.NotFound() return { 'share_id': self.kwargs["share_id"], 'name': share.name or share.id, } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8306513 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/0000775000175000017500000000000000000000000024053 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/__init__.py0000664000175000017500000000000000000000000026152 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/panel.py0000664000175000017500000000165400000000000025532 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ import horizon from openstack_dashboard.dashboards.project import dashboard class UserMessages(horizon.Panel): name = _("User Messages") slug = 'user_messages' permissions = ( 'openstack.services.share', ) dashboard.Project.register(UserMessages) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/tables.py0000664000175000017500000000611300000000000025700 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext_lazy from horizon import exceptions from horizon import tables from horizon.utils.filters import parse_isotime from manila_ui.api import manila def get_date(message): return parse_isotime(message.created_at) class DeleteUserMessage(tables.DeleteAction): policy_rules = (("share", "share:delete_message"),) @staticmethod def action_present(count): return ngettext_lazy( u"Delete User Message", u"Delete User Messages", count ) @staticmethod def action_past(count): return ngettext_lazy( u"Deleted User Message", u"Deleted User Messages", count ) def get_policy_target(self, request, datum=None): project_id = None if datum: project_id = getattr(datum, "project_id", None) return {"project_id": project_id} def delete(self, request, obj_id): obj = self.table.get_object_by_id(obj_id) message_id = self.table.get_object_display(obj) try: manila.messages_delete(request, message_id) except Exception: msg = _('Unable to delete message "%s"') exceptions.handle(self.request, msg % message_id) raise class UserMessageIDColumn(tables.Column): def get_link_url(self, message): return reverse(self.link, args=(message.message_id,)) class UserMessagesTable(tables.DataTable): message_id = tables.Column( "id", verbose_name=_("ID"), link="horizon:project:user_messages:user_messages_detail") message_level = tables.Column( "message_level", verbose_name=_("Message Level") ) resource_type = tables.Column( "resource_type", verbose_name=_("Resource Type")) resource_id = tables.Column( "resource_id", verbose_name=_("Resource ID")) user_message = tables.Column( "user_message", verbose_name=_("User Message")) created_at = tables.Column( get_date, verbose_name=_("Created At")) def get_object_display(self, obj): return obj.id class Meta(object): name = "user_messages" verbose_name = _("User Messages") table_actions = ( tables.NameFilterAction, DeleteUserMessage, ) row_actions = ( DeleteUserMessage, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/tabs.py0000664000175000017500000000212100000000000025352 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.utils.translation import gettext_lazy as _ from horizon import tabs class UserMessagesOverviewTab(tabs.Tab): name = _("User Messages Overview") slug = "user_messages_overview_tab" template_name = "project/user_messages/_detail.html" def get_context_data(self, request): return {"message": self.tab_group.kwargs['message']} class UserMessagesDetailTabs(tabs.TabGroup): slug = "user_messages_detail" tabs = ( UserMessagesOverviewTab, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/templates/0000775000175000017500000000000000000000000026051 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8306513 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/templates/user_messages/0000775000175000017500000000000000000000000030716 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/templates/user_messages/_detail.html0000664000175000017500000000156100000000000033210 0ustar00zuulzuul00000000000000{% load i18n sizeformat parse_date %}

{% trans "User Messages Overview" %}


{% trans "ID" %}
{{ message.id }}
{% trans "Action" %}
{{ message.action_id }}
{% trans "Message" %}
{{ message.user_message }}
{% trans "Message Level" %}
{{ message.message_level }}
{% trans "Resource Type" %}
{{ message.resource_type }}
{% trans "Resource ID" %}
{{ message.resource_id }}
{% trans "Created at" %}
{{ message.created_at|parse_isotime }}
{% trans "Expires at" %}
{{ message.expires_at|parse_isotime }}
{% trans "Request ID" %}
{{ message.request_id }}
././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/templates/user_messages/detail.html0000664000175000017500000000034300000000000033046 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "User Messages Details" %}{% endblock %} {% block main %}
{{ tab_group.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/templates/user_messages/index.html0000664000175000017500000000034500000000000032715 0ustar00zuulzuul00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "User Messages" %}{% endblock %} {% block main %}
{{ user_messages_table.render }}
{% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/urls.py0000664000175000017500000000167000000000000025416 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import re_path from manila_ui.dashboards.project.user_messages import views urlpatterns = [ re_path( r'^$', views.UserMessagesView.as_view(), name='index'), re_path( r'^(?P[^/]+)$', views.UserMessagesDetailView.as_view(), name='user_messages_detail'), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/project/user_messages/views.py0000664000175000017500000000532200000000000025564 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from horizon import exceptions from horizon import tables from horizon import tabs from horizon.utils import memoized from manila_ui.api import manila from manila_ui.dashboards.project.user_messages import tables as um_tables from manila_ui.dashboards.project.user_messages import tabs as um_tabs class UserMessagesView(tables.MultiTableView): table_classes = ( um_tables.UserMessagesTable, ) template_name = "project/user_messages/index.html" page_title = _("User Messages") @memoized.memoized_method def get_user_messages_data(self): try: messages = manila.messages_list(self.request) except Exception: msg = _("Unable to retrieve messages list.") exceptions.handle(self.request, msg) return [] return messages class UserMessagesDetailView(tabs.TabView): tab_group_class = um_tabs.UserMessagesDetailTabs template_name = 'project/user_messages/detail.html' redirect_url = reverse_lazy('horizon:project:user_messages:index') def get_context_data(self, **kwargs): context = super(UserMessagesDetailView, self).get_context_data( **kwargs) message = self.get_data() message_id = message.id context["message"] = message context["message_id"] = message_id context["page_title"] = _("User Message Details: " "%(message_id)s") % ( {'message_id': message_id}) return context @memoized.memoized_method def get_data(self): try: message_id = self.kwargs['message_id'] message = manila.messages_get(self.request, message_id) except Exception: exceptions.handle( self.request, _('Unable to retrieve user message detail.'), redirect=self.redirect_url) return message def get_tabs(self, request, *args, **kwargs): message = self.get_data() return self.tab_group_class(request, message=message, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/dashboards/utils.py0000664000175000017500000001054200000000000021254 0ustar00zuulzuul00000000000000# 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 base64 import binascii import re from django.forms import ValidationError from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ html_escape_table = { "&": "&", '"': """, "'": "'", ">": ">", "<": "<", } def html_escape(text): return ''.join(html_escape_table.get(s, s) for s in text) def parse_str_meta(meta_s): """Parse multiline string with data from form. :option meta_s: str - string with keys and values :returns: tuple of dict with key-value for set and list with keys for unset :raises: ValidationError """ strings = [el.strip() for el in meta_s.split("\n") if len(el.strip()) > 0] set_dict = {} unset_list = [] msg = "" for string in strings: if string.count("=") == 0: # Key for unsetting key = string.strip(r'\"\' ') if len(key) not in range(1, 256): msg = _("Key '%s' has improper length.") % key elif " " in key: msg = _("Key can not contain spaces. See string '%s'.") % key elif key not in unset_list: unset_list.append(key) else: # Key-value pair for setting pair = [p.strip(r'\"\' ') for p in string.split("=", 1)] if not all(len(p) in range(1, 256) for p in pair): msg = _("All keys and values must be in range from 1 to 255.") elif pair[0] in list(set_dict.keys()): msg = _("Duplicated keys '%s'.") % pair[0] elif " " in pair[0]: msg = _("Keys should not contain spaces. " "Error in '%s'.") % string else: set_dict[pair[0]] = pair[1] duplicated_keys = [uk for uk in unset_list if uk in list(set_dict.keys())] if duplicated_keys: msg = _("Duplicated keys '%s'.") % str(duplicated_keys) if msg: raise ValidationError(message=msg) return set_dict, unset_list def metadata_to_str(metadata, meta_visible_limit=4, text_length_limit=25): # Only convert dictionaries if not hasattr(metadata, 'keys'): return metadata meta = [] meta_keys = sorted(metadata.keys()) meta_keys = meta_keys[:meta_visible_limit] for k in meta_keys: k_shortenned = k if len(k) > text_length_limit: k_shortenned = k[:text_length_limit] + '...' v = metadata[k] v = v if isinstance(v, str) else str(v) if len(v) > text_length_limit: v = v[:text_length_limit] + '...' meta.append("%s = %s" % (html_escape(k_shortenned), html_escape(v))) meta_str = "
".join(meta) if len(metadata.keys()) > meta_visible_limit and meta_str[-3:] != "...": meta_str += '...' return mark_safe(meta_str) def get_nice_security_service_type(security_service): type_mapping = { 'ldap': 'LDAP', 'active_directory': 'Active Directory', 'kerberos': 'Kerberos', } return type_mapping.get(security_service.type, security_service.type) def calculate_longest_str_size(str_list): size = 40 for str_val in str_list: current_size = len(str_val) if current_size > size: size = current_size return size def transform_dashed_name(name): """Add or remove unicode text separators & transformations for hyphens.""" if not name: return try: return base64.b32decode( name.replace('_', '=').upper().encode()).decode() except (binascii.Error, UnicodeDecodeError): if re.search(r'^[a-z_\d]+$', name): return name # leave as-is names without dashes and capitals else: return base64.b32encode(name.encode()).decode().lower().replace( '=', '_') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/exceptions.py0000664000175000017500000000175600000000000020172 0ustar00zuulzuul00000000000000# Copyright 2012 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manilaclient import exceptions as manilaclient UNAUTHORIZED = ( manilaclient.AuthorizationFailure, manilaclient.Unauthorized, ) NOT_FOUND = ( manilaclient.NotFound, ) RECOVERABLE = ( manilaclient.ClientException, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/features.py0000664000175000017500000000361500000000000017623 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ This module stores functions that return boolean values and say which manila features are enabled and which are disabled among those that are optional for manila UI. These functions are required mostly for complex features, which consist of more than one logical part in manila UI and requires appropriate logic change in more than 1 place. For example, to disable share groups feature we need to do following: - Remove 'share_groups' panel from 'share groups' panel group in each dashboard. - Disable or do not register URLs for disabled features, so, no one will be able to request disabled features knowing direct URL. - Add/remove buttons for other (not disabled) features that are related to it somehow. """ from django.conf import settings from horizon.utils import memoized @memoized.memoized def is_share_groups_enabled(): manila_config = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) return manila_config.get('enable_share_groups', True) @memoized.memoized def is_replication_enabled(): manila_config = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) return manila_config.get('enable_replication', True) @memoized.memoized def is_migration_enabled(): manila_config = getattr(settings, 'OPENSTACK_MANILA_FEATURES', {}) return manila_config.get('enable_migration', True) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8306513 manila-ui-11.0.0/manila_ui/local/0000775000175000017500000000000000000000000016520 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/__init__.py0000664000175000017500000000000000000000000020617 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8306513 manila-ui-11.0.0/manila_ui/local/enabled/0000775000175000017500000000000000000000000020112 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_80_manila_admin_add_share_panel_group.py0000664000175000017500000000256200000000000030135 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # The slug of the panel group to be added to HORIZON_CONFIG. Required. PANEL_GROUP = 'share' # The display name of the PANEL_GROUP. Required. PANEL_GROUP_NAME = 'Share' # The slug of the dashboard the PANEL_GROUP associated with. Required. PANEL_GROUP_DASHBOARD = 'admin' EXTRA_TABS = { 'openstack_dashboard.dashboards.admin.defaults.tabs.DefaultsTabs': ( 'manila_ui.dashboards.admin.defaults.tabs.ShareQuotasTab', ), } EXTRA_STEPS = { 'openstack_dashboard.dashboards.identity.projects.workflows.UpdateQuota': ( 'manila_ui.dashboards.identity.projects.workflows.UpdateShareQuota', ), 'openstack_dashboard.dashboards.admin.defaults.workflows.' 'UpdateDefaultQuotas': ( 'manila_ui.dashboards.admin.defaults.workflows.' 'UpdateDefaultShareQuotasStep', ), } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_80_manila_project_add_share_panel_group.py0000664000175000017500000000201600000000000030505 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui import exceptions # The slug of the panel group to be added to HORIZON_CONFIG. Required. PANEL_GROUP = 'share' # The display name of the PANEL_GROUP. Required. PANEL_GROUP_NAME = 'Share' # The slug of the dashboard the PANEL_GROUP associated with. Required. PANEL_GROUP_DASHBOARD = 'project' ADD_EXCEPTIONS = { 'recoverable': exceptions.RECOVERABLE, 'not_found': exceptions.NOT_FOUND, 'unauthorized': exceptions.UNAUTHORIZED, } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9010_manila_admin_add_shares_panel_to_share_panel_group.py0000664000175000017500000000130100000000000033513 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'shares' ADD_PANEL = 'manila_ui.dashboards.admin.shares.panel.Shares' ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=manila-ui-11.0.0/manila_ui/local/enabled/_9010_manila_project_add_shares_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9010_manila_project_add_shares_panel_to_share_panel_group.0000664000175000017500000000130500000000000033524 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'shares' ADD_PANEL = 'manila_ui.dashboards.project.shares.panel.Shares' ././@PaxHeader0000000000000000000000000000021500000000000011453 xustar0000000000000000119 path=manila-ui-11.0.0/manila_ui/local/enabled/_9020_manila_admin_add_share_snapshots_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9020_manila_admin_add_share_snapshots_panel_to_share_panel0000664000175000017500000000133300000000000033575 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_snapshots' ADD_PANEL = 'manila_ui.dashboards.admin.share_snapshots.panel.ShareSnapshots' ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/manila_ui/local/enabled/_9020_manila_project_add_share_snapshots_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9020_manila_project_add_share_snapshots_panel_to_share_pan0000664000175000017500000000133700000000000033636 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'share_snapshots' ADD_PANEL = 'manila_ui.dashboards.project.share_snapshots.panel.ShareSnapshots' ././@PaxHeader0000000000000000000000000000021100000000000011447 xustar0000000000000000115 path=manila-ui-11.0.0/manila_ui/local/enabled/_9030_manila_admin_add_share_types_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9030_manila_admin_add_share_types_panel_to_share_panel_gro0000664000175000017500000000131700000000000033571 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_types' ADD_PANEL = 'manila_ui.dashboards.admin.share_types.panel.ShareTypes' ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=manila-ui-11.0.0/manila_ui/local/enabled/_9040_manila_admin_add_share_networks_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9040_manila_admin_add_share_networks_panel_to_share_panel_0000664000175000017500000000133000000000000033565 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_networks' ADD_PANEL = 'manila_ui.dashboards.admin.share_networks.panel.ShareNetworks' ././@PaxHeader0000000000000000000000000000021600000000000011454 xustar0000000000000000120 path=manila-ui-11.0.0/manila_ui/local/enabled/_9040_manila_project_add_share_networks_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9040_manila_project_add_share_networks_panel_to_share_pane0000664000175000017500000000133400000000000033634 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'share_networks' ADD_PANEL = 'manila_ui.dashboards.project.share_networks.panel.ShareNetworks' ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/manila_ui/local/enabled/_9050_manila_admin_add_security_services_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9050_manila_admin_add_security_services_panel_to_share_pan0000664000175000017500000000135000000000000033624 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'security_services' ADD_PANEL = ( 'manila_ui.dashboards.admin.security_services.panel.SecurityServices') ././@PaxHeader0000000000000000000000000000022100000000000011450 xustar0000000000000000123 path=manila-ui-11.0.0/manila_ui/local/enabled/_9050_manila_project_add_security_services_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9050_manila_project_add_security_services_panel_to_share_p0000664000175000017500000000135400000000000033667 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'security_services' ADD_PANEL = ( 'manila_ui.dashboards.project.security_services.panel.SecurityServices') ././@PaxHeader0000000000000000000000000000021300000000000011451 xustar0000000000000000117 path=manila-ui-11.0.0/manila_ui/local/enabled/_9060_manila_admin_add_share_servers_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9060_manila_admin_add_share_servers_panel_to_share_panel_g0000664000175000017500000000132500000000000033557 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_servers' ADD_PANEL = 'manila_ui.dashboards.admin.share_servers.panel.ShareServers' ././@PaxHeader0000000000000000000000000000021500000000000011453 xustar0000000000000000119 path=manila-ui-11.0.0/manila_ui/local/enabled/_9070_manila_admin_add_share_instances_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9070_manila_admin_add_share_instances_panel_to_share_panel0000664000175000017500000000133300000000000033547 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_instances' ADD_PANEL = 'manila_ui.dashboards.admin.share_instances.panel.ShareInstances' ././@PaxHeader0000000000000000000000000000021200000000000011450 xustar0000000000000000116 path=manila-ui-11.0.0/manila_ui/local/enabled/_9080_manila_admin_add_share_groups_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9080_manila_admin_add_share_groups_panel_to_share_panel_gr0000664000175000017500000000153700000000000033576 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui import features PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_groups' if features.is_share_groups_enabled(): ADD_PANEL = 'manila_ui.dashboards.admin.share_groups.panel.ShareGroups' else: REMOVE_PANEL = not features.is_share_groups_enabled() ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=manila-ui-11.0.0/manila_ui/local/enabled/_9080_manila_project_add_share_groups_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9080_manila_project_add_share_groups_panel_to_share_panel_0000664000175000017500000000154300000000000033620 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui import features PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'share_groups' if features.is_share_groups_enabled(): ADD_PANEL = 'manila_ui.dashboards.project.share_groups.panel.ShareGroups' else: REMOVE_PANEL = not features.is_share_groups_enabled() ././@PaxHeader0000000000000000000000000000022300000000000011452 xustar0000000000000000125 path=manila-ui-11.0.0/manila_ui/local/enabled/_9085_manila_admin_add_share_group_snapshots_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9085_manila_admin_add_share_group_snapshots_panel_to_share0000664000175000017500000000161700000000000033652 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui import features PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_group_snapshots' if features.is_share_groups_enabled(): ADD_PANEL = ('manila_ui.dashboards.admin.share_group_snapshots.panel.' 'ShareGroupSnapshots') else: REMOVE_PANEL = not features.is_share_groups_enabled() ././@PaxHeader0000000000000000000000000000022500000000000011454 xustar0000000000000000127 path=manila-ui-11.0.0/manila_ui/local/enabled/_9085_manila_project_add_share_group_snapshots_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9085_manila_project_add_share_group_snapshots_panel_to_sha0000664000175000017500000000162300000000000033676 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui import features PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'share_group_snapshots' if features.is_share_groups_enabled(): ADD_PANEL = ('manila_ui.dashboards.project.share_group_snapshots.panel.' 'ShareGroupSnapshots') else: REMOVE_PANEL = not features.is_share_groups_enabled() ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/manila_ui/local/enabled/_9090_manila_admin_add_share_group_types_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9090_manila_admin_add_share_group_types_panel_to_share_pan0000664000175000017500000000157000000000000033624 0ustar00zuulzuul00000000000000# Copyright 2017 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui import features PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'share_group_types' if features.is_share_groups_enabled(): ADD_PANEL = ( 'manila_ui.dashboards.admin.share_group_types.panel.ShareGroupTypes') else: REMOVE_PANEL = not features.is_share_groups_enabled() ././@PaxHeader0000000000000000000000000000021300000000000011451 xustar0000000000000000117 path=manila-ui-11.0.0/manila_ui/local/enabled/_9095_manila_admin_add_user_messages_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9095_manila_admin_add_user_messages_panel_to_share_panel_g0000664000175000017500000000132700000000000033563 0ustar00zuulzuul00000000000000# Copyright 2020 Red Hat Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'admin' PANEL_GROUP = 'share' PANEL = 'user_messages' ADD_PANEL = ('manila_ui.dashboards.admin.user_messages.panel.UserMessages') ././@PaxHeader0000000000000000000000000000021500000000000011453 xustar0000000000000000119 path=manila-ui-11.0.0/manila_ui/local/enabled/_9095_manila_project_add_user_messages_panel_to_share_panel_group.py 22 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/_9095_manila_project_add_user_messages_panel_to_share_panel0000664000175000017500000000133300000000000033630 0ustar00zuulzuul00000000000000# Copyright 2020 Red Hat Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. PANEL_DASHBOARD = 'project' PANEL_GROUP = 'share' PANEL = 'user_messages' ADD_PANEL = ('manila_ui.dashboards.project.user_messages.panel.UserMessages') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/enabled/__init__.py0000664000175000017500000000000000000000000022211 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8306513 manila-ui-11.0.0/manila_ui/local/local_settings.d/0000775000175000017500000000000000000000000021754 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/local/local_settings.d/_90_manila_shares.py0000664000175000017500000000266200000000000025611 0ustar00zuulzuul00000000000000# Copyright 2016 Red Hat Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.conf import settings settings.POLICY_FILES.update({ 'share': 'manila_policy.yaml', }) settings.DEFAULT_POLICY_FILES.update({ 'share': 'default_policies/manila.yaml' }) # Sample # settings.LOGGING['loggers'].update({ # 'manilaclient': { # 'handlers': ['console'], # 'level': 'DEBUG', # 'propagate': False, # } # }) # The OPENSTACK_MANILA_FEATURES settings can be used to enable or disable # the UI for the various services provided by Manila. OPENSTACK_MANILA_FEATURES = { 'enable_share_groups': True, 'enable_replication': True, 'enable_migration': True, 'enable_public_share_type_creation': True, 'enable_public_share_group_type_creation': True, 'enable_public_shares': True, 'enabled_share_protocols': ['NFS', 'CIFS', 'GlusterFS', 'HDFS', 'CephFS', 'MapRFS'], } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/0000775000175000017500000000000000000000000016665 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/cs/0000775000175000017500000000000000000000000017272 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8306513 manila-ui-11.0.0/manila_ui/locale/cs/LC_MESSAGES/0000775000175000017500000000000000000000000021057 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/cs/LC_MESSAGES/django.po0000664000175000017500000004601400000000000022666 0ustar00zuulzuul00000000000000# Stanislav Ulrych , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-11-24 11:18+0000\n" "Last-Translator: Stanislav Ulrych \n" "Language-Team: Czech\n" "Language: cs\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(kvóta překročena)" msgid "Access Level" msgstr "Úroveň přístupu" msgid "Access To" msgstr "Přístup do" msgid "Access Type" msgstr "Typ přístupu" msgid "Access to" msgstr "Přístup do" msgctxt "Current status of share network" msgid "Active" msgstr "Aktivní" msgctxt "Current status of share server" msgid "Active" msgstr "Aktivní" msgid "Add" msgstr "Přidat" msgid "Add Rule" msgstr "Přidat pravidlo" msgid "Add Security Service" msgstr "Přidat bezpečnostní službu" msgid "Add rule" msgstr "Přidat pravidlo" msgid "Add security services to share network." msgstr "Přidat bezpečnostní služby do sítě sdílení." msgid "All keys and values must be in range from 1 to 255." msgstr "Všechny klíče a hodnoty musí být v rozsau 1 až 255." msgid "Allow project access to share type." msgstr "Povolit projektu přístup k typu sdílení" msgid "At least one security service must be specified." msgstr "Musí být zadána alespoň jedna bezpečnostní služba." msgid "Availability Zone" msgstr "Zóna dostupnosti" msgid "Availability zone" msgstr "Zóna dostupnosti" msgctxt "Current status of replica" msgid "Available" msgstr "Dostupné" msgctxt "Current status of share" msgid "Available" msgstr "Dostupné" msgctxt "Current status of snapshot" msgid "Available" msgstr "Dostupné" msgid "Available projects" msgstr "Dostupné projekty" msgid "Available security services" msgstr "Dostupné bezpečnostní služby" msgid "Cancel Migration" msgstr "Zrušit migraci" msgid "Cancel migration" msgstr "Zrušit migraci" msgid "Cancel migration of a Share" msgstr "Zrušit migraci sdílení" msgid "Choose a snapshot" msgstr "Zvolte snapshot" msgid "Complete Migration" msgstr "Dokončit migraci" msgid "Complete migration" msgstr "Dokončit migraci" msgid "Complete migration of a Share" msgstr "Dokončit migraci sdílení" msgid "Confirm Migration Cancelling of Share" msgstr "Potvrdit zrušení migrace sdílení" msgid "Confirm Migration Completion of Share" msgstr "Potvrdit dokončení migraci sdílení" msgid "Confirm Password" msgstr "Potvrdit heslo" msgid "Create" msgstr "Vytvořit" msgid "Create Replica" msgstr "Vytvořit repliku" msgid "Create Security Service" msgstr "Vytvořit bezpečnostní službu" msgid "Create Share" msgstr "Vytvořit sdílení" msgid "Create Share Network" msgstr "Vytvořit síť sdílení" msgid "Create Share Snapshot" msgstr "Vytvořit snapshot sdílení." msgid "Create Share Type" msgstr "Vytvořit typ sdílení" msgid "Create a Share" msgstr "Vytvořit sdílení" msgid "Created At" msgstr "Vytvořeno" msgctxt "Current status of replica" msgid "Creating" msgstr "Vytváření" msgctxt "Current status of share" msgid "Creating" msgstr "Vytváření" msgctxt "Current status of share server" msgid "Creating" msgstr "Vytváření" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Výtvářeno" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Vytváření repliky pro sdílení \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Vytváření pravidla pro \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Vytváření sdílení \"%s\"" #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Vytváření snapshotu sdílení \"%s\"." msgid "Current Size (GiB)" msgstr "Současná velikost (GiB)" msgid "DNS IP" msgstr "DNS IP" msgctxt "Current status of replica" msgid "Deleting" msgstr "Mazání" msgctxt "Current status of share" msgid "Deleting" msgstr "Mazání" msgid "Description" msgstr "Popis" msgid "Domain" msgstr "Doména" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Volby driveru ('volume_id' pro generický driver atd.)" #, python-format msgid "Duplicated keys '%s'." msgstr "Duplikátní klíče '%s'." msgid "Edit" msgstr "Upravit" msgid "Edit Security Service" msgstr "Upravit bezpečnostní službu" msgid "Edit Share" msgstr "Upravit sdílení" msgid "Edit Share Metadata" msgstr "Upravit metadata sdílení" msgid "Edit Share Network" msgstr "Upravit síť sdílení" msgctxt "Current status of replica" msgid "Error" msgstr "Chyba" msgctxt "Current status of share" msgid "Error" msgstr "Chyba" msgctxt "Current status of share network" msgid "Error" msgstr "Chyba" msgctxt "Current status of share server" msgid "Error" msgstr "Chyba" msgctxt "Current status of snapshot" msgid "Error" msgstr "Chyba" msgid "Extra specs" msgstr "Dodatečné specifikace" msgid "Force Host Assisted Migration" msgstr "Vynutit migraci asistovanou hostitelem" msgid "From here you can update share network info. " msgstr "Zde můžete upravit informace o síti sdílení." msgid "Host" msgstr "Hostitel" msgid "Host of share" msgstr "Hostitel sdílení" msgid "Host to migrate share" msgstr "Hostitel na který má být sdílení migrováno" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "Hostitel, na němž se sdílení nachází, příklad: some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "Verze IP" msgid "Id" msgstr "Id" msgctxt "Current status of share server" msgid "In-use" msgstr "Používá se" msgctxt "Current status of snapshot" msgid "In-use" msgstr "Používá se" msgctxt "Current status of share network" msgid "Inactive" msgstr "Neaktivní" #, python-format msgid "Key '%s' has improper length." msgstr "Klíč '%s' nemá správnou délku." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Klíč nemůže obsahovat mezery. Viz řetězec '%s'." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Klíče nemohou obsahovat mezery. Chyba v '%s'." msgid "Manage" msgstr "Spravovat" msgctxt "Current status of share" msgid "Manage Error" msgstr "Spravovat chyby" msgid "Manage Rules" msgstr "Správa pravidel" msgid "Manage Share Type Access" msgstr "Spravovat přístup typů sdílení" msgid "Metadata" msgstr "Metadata" msgid "Migrate Share" msgstr "Migrovat sdílení" msgid "Migrate a Share" msgstr "Migrovat sdílení" msgctxt "Current status of share" msgid "Migrating" msgstr "Migrace" msgctxt "Current status of share" msgid "Migrating to" msgstr "Migrace do" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "Migrace sdílení %(name)s je hotová z %(progress)s procent." msgid "Name" msgstr "Název" msgid "Network Type" msgstr "Typ sítě" msgid "Networks" msgstr "Sítě" msgid "Neutron Net" msgstr "Neutron síť" msgid "Neutron Subnet" msgstr "Neutron podsíť" msgid "New Size (GiB)" msgstr "Nová velkost (GiB)" msgid "New share network to be set in migrated share" msgstr "Nová síť sdílení pro zmigrované sdílení" msgid "No projects found." msgstr "Nenalezeny žádné projekty." msgid "No projects selected." msgstr "Nevybrány žádné projekty." msgid "No security services found." msgstr "Nenalezeny žádné bezpečnostní služby." msgid "No security services selected." msgstr "Nevybrány žádné bezpečnostní služby." msgid "No source, empty share" msgstr "Žádný zdroj, prázdné sdílení" msgid "Overview" msgstr "Přehled" msgid "Password" msgstr "Heslo" msgid "Passwords do not match." msgstr "Hesla se neshodují." msgid "Preserve Metadata" msgstr "Zachovat metadata" msgid "Project" msgstr "Projekt" msgid "Projects with access to share type" msgstr "Projekty s přístupem k typu sdílení" msgid "Protocol" msgstr "Protokol" msgid "Public" msgstr "Veřejný" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Detaily repliky: %(replica_display_name)s" msgid "Replica State" msgstr "Stav repliky" msgid "Rules" msgstr "Pravidla" msgid "Save Changes" msgstr "Uložit změny" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Detaily bezpečnostní služby: %(service_display_name)s" msgid "Security Services" msgstr "Bezpečnostní služby" msgid "Security services within share network" msgstr "Bezpečnostní služby v síti sdílení" msgid "Segmentation Id" msgstr "ID segmentace" msgid "Selected projects" msgstr "Vybrané projekty" msgid "Selected security services" msgstr "Vybrané bezpečnostní služby" msgid "Server" msgstr "Server" msgid "Set Replica as Active" msgstr "Nastavit repliku jako aktivní" msgid "Set as Active" msgstr "Nastavit jako aktivní" msgid "Set maximum quotas for the project." msgstr "Nastavit maximální kvóty pro projekt." #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Nastavování repliky \"%s\" jako aktivní..." msgid "Share" msgstr "Sdílení" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Detaily sdílení: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Detaily sdílení: %(share_name)s" msgid "Share ID" msgstr "Share ID" #, python-format msgid "Share Instance Details: %s" msgstr "Detaily instance sdílení: %s" msgid "Share Instances" msgstr "Instance sdílení" msgid "Share Name" msgstr "Název sdílení" msgid "Share Network" msgstr "Síť sdílení" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Detaily sítě sdílení: %(network_display_name)s" msgid "Share Network Info" msgstr "Informace o síti sdílení" msgid "Share Networks" msgstr "Sítě sdílení" msgid "Share Protocol" msgstr "Protokol sdílení" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Repliky sdílení: %(share_display_name)s" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Pravidla sdílení: %(share_display_name)s" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Detaily serveru sdílení: %(server_name)s" msgid "Share Server Id" msgstr "Id serveru sdílení" msgid "Share Servers" msgstr "Servery sdílení" msgid "Share Snapshots" msgstr "Snapshoty sdílení" msgid "Share Snapshots Storage" msgstr "Úložiště snapshotů sdílení" msgid "Share Source" msgstr "Zdroj sdílení" msgid "Share Storage" msgstr "Sdílené úložiště" msgid "Share Type" msgstr "Typ sdílení" msgid "Share Types" msgstr "Typy sdílení" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Sdílení nemůže být zvětšeno na %(req)iGiB, protože máte dostupných pouze " "%(avail)iGiB z vaší kvóty." msgid "Share name to be assigned" msgstr "Název sdílení, který bude přidělen." #, python-format msgid "Share replica %s has been deleted." msgstr "Replika sdílení %s byla smazána." #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "Velikost sdílení musí být větší nebo roven velikosti snapshotu (%sGiB)" msgid "Shares" msgstr "Sdílení" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Velikost" msgid "Size (GiB)" msgstr "Velikost (GiB)" msgid "Snapshot" msgstr "Snapshot" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Detaily snapshot: %(snapshot_display_name)s" msgid "Snapshot Overview" msgstr "Přehled snapshotů" msgid "Source" msgstr "Zdroj" msgid "Start migration" msgstr "Spustit migraci" msgid "Status" msgstr "Status" #, python-format msgid "Successfully created security service: %s" msgstr "Úspěšně vytvořena bezpečnostní služba: %s" #, python-format msgid "Successfully created share network: %s" msgstr "Úspěšně vytvořena síť sdílení: %s" #, python-format msgid "Successfully created share type: %s" msgstr "Úspěšně vytvořen typ sdílení: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "Požadavek na zrušení migrace sdílení odeslán úspěšně: %s." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "Požadavek na dokončení migrace sdílení odeslán úspěšně: %s." #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Žádost o správu sdílení byla úspěšně odeslána: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "Požadavek na migraci sdílení odeslán úspěšně: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "Žádost o zrušení správy sdílení byla úspěšně odeslána: %s" #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Úspěšně aktualizována bezpečnostní služba: %s" #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "Velikost sdílení nemůže být menší než velikost snapshotu (%sGiB)" msgid "Type" msgstr "Typ" msgid "Unable to add rule." msgstr "Nelze přidat pravidlo." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "Momentálně nelze zrušit migraci sdílení %s." #, python-format msgid "Unable to complete migration of share %s." msgstr "Nelze dokončit migraci sdílení %s." msgid "Unable to create security service." msgstr "Nelze vytvořit bezpečnostní službu." msgid "Unable to create share network." msgstr "Nelze vytvořit sít sdílení." msgid "Unable to create share replica." msgstr "Nelze vytvořit repliku sdílení." msgid "Unable to create share snapshot." msgstr "Nelze vytvořit snapshot sdílení." msgid "Unable to create share type." msgstr "Nelze vytvořit typ sdílení." msgid "Unable to create share." msgstr "Nelze vytvořit sdílení." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Nelze smazat pravidlo \"%s\"." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Nelze smazat sdílení \"%s\". " #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "Nelze smazat snapshot \"%s\". Jedno nebo více sdílení na něm závisí." msgid "Unable to get information about share type access." msgstr "Nelze získat informaci o přístupu ke sdílení" msgid "Unable to get list of projects." msgstr "Nelze získat seznam projektů." msgid "Unable to get the security services hosts" msgstr "Nelze získat hostitele bezpečnostních služeb" msgid "Unable to load the specified snapshot." msgstr "Nelze načíst zadaný snapshot." msgid "Unable to manage share" msgstr "Nelze spravovat sdílení." #, python-format msgid "Unable to migrate share %s." msgstr "Nelze migrovat sdílení %s." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "Momentálně nelze získat stav procesu migrace sdílení %s." #, python-format msgid "Unable to resync replica '%s'." msgstr "Nelze synchronizovat repliku '%s'." msgid "Unable to retrieve list of projects." msgstr "Nelze získat seznam projektů." msgid "Unable to retrieve quotas." msgstr "Nelze získat kvóty." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Nelze získat detaily o bezpečnostní službě '%s'." msgid "Unable to retrieve security services" msgstr "Nelze získat bezpečnostní služby." msgid "Unable to retrieve security_service." msgstr "Nelze získat security_service." msgid "Unable to retrieve share details." msgstr "Nelze získat detaily sdílení." msgid "Unable to retrieve share instance details." msgstr "Nelze získat detaily instance sdílení." msgid "Unable to retrieve share instances." msgstr "Nelze získat instance sdílení." msgid "Unable to retrieve share list." msgstr "Nelze získat seznam sdílení." msgid "Unable to retrieve share network details." msgstr "Nelze získat detaily sítě sdílení." msgid "Unable to retrieve share network." msgstr "Nelze získat sít sdílení." msgid "Unable to retrieve share networks" msgstr "Nelze získat sítě sdílení" msgid "Unable to retrieve share replicas." msgstr "Nelze získat repliky sdílení." msgid "Unable to retrieve share rules." msgstr "Nelze získat pravidla sdílení." msgid "Unable to retrieve share server details." msgstr "Nelze získat detaily serveru sdílení." msgid "Unable to retrieve share servers" msgstr "Nelze získat servery sdílení" msgid "Unable to retrieve share snapshots list." msgstr "Nelze získat seznam snapshotů sdílení." msgid "Unable to retrieve share snapshots." msgstr "Nelze získat snapshoty sdílení." msgid "Unable to retrieve share." msgstr "Nelze získat sdílení." #, python-format msgid "Unable to retrieve share. %s" msgstr "Nelze získat sdílení. %s" msgid "Unable to retrieve share_type." msgstr "Nelze získat share_type." msgid "Unable to retrieve snapshot details." msgstr "Nelze získat detaily snapshotu." msgid "Unable to retrieve snapshot." msgstr "Nelze získat snapshot." msgid "Unable to retrieve volume details." msgstr "Nelze získat detaily svazku." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Nelze nastavit repliku '%s' jako aktivní." msgid "Unable to unmanage share." msgstr "Nelze zrušit správu sdílení." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Nelze aktualizovat přístup pro typ sdílení \"%s\"." msgid "Unable to update default quotas." msgstr "Nelze aktualizovat výchozí kvóty." msgid "Unable to update security service." msgstr "Nelze aktualizovat bezpečnostní službu." msgid "Unable to update share metadata." msgstr "Nelze aktualizovat metadata sdílení." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Nelze aktualizovat síť sdílení \"%s\"." msgid "Unable to update share network." msgstr "Nelze aktualizovat síť sdílení." msgid "Unable to update share type." msgstr "Nelze aktualizovat typ sdílení." msgid "Unable to update share." msgstr "Nelze aktualizovat sdílení." msgid "Unknown" msgstr "Neznámé" msgid "Unmanage" msgstr "Zrušit správu" msgid "Update" msgstr "Aktualizovat" msgid "Update Share Network" msgstr "Aktualizovat síť sdílení" msgid "Updated At" msgstr "Aktualizováno" #, python-format msgid "Updated access for share type \"%s\"." msgstr "Aktualizován přístup pro typ sdílení \"%s\"." #, python-format msgid "Updated share network \"%s\"." msgstr "Aktualizována síť sdílení \"%s\"." #, python-format msgid "Updating share \"%s\"" msgstr "Aktualizace sdílení \"%s\"" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Aktualizace metadat sdílení \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Aktualizace sítě sdílení \"%s\"" msgid "Use snapshot as a source" msgstr "Použít snapshot jako zdroj" msgid "User" msgstr "Uživatel" msgid "Writable" msgstr "Zapisovatelný" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/de/0000775000175000017500000000000000000000000017255 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/de/LC_MESSAGES/0000775000175000017500000000000000000000000021042 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/de/LC_MESSAGES/django.po0000664000175000017500000014635100000000000022656 0ustar00zuulzuul00000000000000# Frank Kloeker , 2016. #zanata # Robert Simai , 2016. #zanata # Frank Kloeker , 2017. #zanata # Robert Simai , 2017. #zanata # Frank Kloeker , 2018. #zanata # Reik Keutterling , 2018. #zanata # Robert Simai , 2018. #zanata # Andreas Jaeger , 2019. #zanata # Andreas Jaeger , 2020. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2020-04-26 06:14+0000\n" "Last-Translator: Andreas Jaeger \n" "Language-Team: German\n" "Language: de\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "" "\"Manage\" an existing share from a Manila host. This will make the share " "visible within OpenStack.

This is equivalent to the 'manila " "manage' command." msgstr "" "\"Verwalten\" einer vorhandenen Freigabe von einem Manila-Host Dadurch wird " "die Freigabe in OpenStack sichtbar.

Dies entspricht dem Befehl " " 'manila manage' ." #, python-format msgid "%(used)s of %(quota)s GiB Used" msgstr "%(used)s von %(quota)s GiB verwendet" #, python-format msgid "%(used)s of %(quota)s Used" msgstr "%(used)s von %(quota)s verwendet" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(Kontingent überschritten)" msgid "Access Key" msgstr "Zugriffsschlüssel" msgid "Access Level" msgstr "Zugriffsstufe" msgid "Access Level:" msgstr "Zugriffsstufe:" msgid "Access Rules" msgstr "Zugriffsregeln" msgid "Access To" msgstr "Zugriff auf" msgid "Access Type" msgstr "Zugriffstyp" msgid "Access to" msgstr "Zugriff auf" msgid "Access to:" msgstr "Zugriff auf:" msgctxt "Current status of share network" msgid "Active" msgstr "Aktiv" msgctxt "Current status of share server" msgid "Active" msgstr "Aktiv" msgid "Add" msgstr "Hinzufügen" msgid "Add Rule" msgstr "Regel hinzufügen" msgid "Add Security Service" msgstr "Sicherheitsdienst hinzufügen" msgid "Add Share Snapshot Rule" msgstr "Freigabe Schattenkopie Regel hinzufügen" msgid "" "Add policy rule to snapshot, 'ip' rule represents ip address, 'user' rule " "represents username or usergroup, 'cephx' rule represents ceph auth ID, and " "'cert' rule represents certificate." msgstr "" "Hinzufügen der Richtlinienregel zum Snapshot, \"ip\"-Regel stellt IP-Adresse " "dar, \"user\"-Regel stellt Benutzername oder Benutzergruppe dar, \"cephx\"-" "Regel stellt Ceph-Authentifizierungs-ID dar und \"cert\"-Regel stellt " "Zertifikat dar." msgid "Add rule" msgstr "Regel hinzufügen" msgid "Add security services to share network." msgstr "Füge Sicherheitsdienst zu Freigabenetzwerk hinzu." msgid "All keys and values must be in range from 1 to 255." msgstr "Alle Schlüssel und Werte müssen im Bereich zwischen 1 und 255 liegen." msgid "All pairs that are in field for left are set for this metadata." msgstr "" "Alle Paare, die sich im Feld für Links befinden, werden für diese Metadaten " "festgelegt." msgid "All pairs that are in field for left are set for this share group type." msgstr "" "Alle Paare, die sich im Feld für links befinden, werden für diesen " "Freigabegruppentyp festgelegt." msgid "All pairs that are in field for left are set for this share type." msgstr "" "Alle Paare, die sich im Feld für links befinden, werden für diesen " "Freigabegruppentyp festgelegt." msgid "Allow project access to share group type." msgstr "Erlaube Projektzugriff zum Gruppenfreigabentyp" msgid "Allow project access to share type." msgstr "Erlaube Projekt Zugriff auf Freigabetyp." msgid "At least one security service must be specified." msgstr "Wenigstens ein Sicherheitsdienst muss angegeben werden." msgid "At least one share type must be specified." msgstr "Es muss mindestens ein Freigabetyp angegeben werden." msgid "Availability Zone" msgstr "Verfügbarkeitszone" msgid "Availability zone" msgstr "Verfügbarkeitszone" msgctxt "Current status of replica" msgid "Available" msgstr "Verfügbar" msgctxt "Current status of share" msgid "Available" msgstr "Verfügbar" msgctxt "Current status of snapshot" msgid "Available" msgstr "Verfügbar" msgid "Available networks" msgstr "Verfügbare Netzwerke" msgid "Available projects" msgstr "Verfügbare Projekte" msgid "Available security services" msgstr "Verfügbare Sicherheitsdienste" msgid "Cancel" msgstr "Abbrechen" msgid "Cancel Migration" msgstr "Migration abbrechen" msgid "Cancel migration" msgstr "Migration abbrechen" msgid "Cancel migration of a Share" msgstr "Migration einer Freigabe abbrechen" msgid "" "Cancel migration of a migrating share.

This is equivalent to the " "'manila migration-cancel' command." msgstr "" "Brechen Sie die Migration einer migrierenden Freigabe ab.

Dies " "entspricht dem Befehl 'manila migration-cancel' ." msgid "Capabilities" msgstr "Fähigkeiten" msgid "Choose a snapshot" msgstr "Wählen Sie eine Schattenkopie" msgid "Complete Migration" msgstr "Migration abschliessen" msgid "Complete migration" msgstr "Migration abschließen" msgid "Complete migration of a Share" msgstr "Migration einer Freigabe abschliessen" msgid "" "Complete migration of a migrating share to another Manila host. This " "operation is expected to be disruptive.

This is equivalent to the " "'manila migration-complete' command." msgstr "" "Vollständige Migration einer migrierenden Freigabe auf einen anderen Manila-" "Host Diese Operation wird voraussichtlich störend sein.

Dies " "entspricht dem Befehl 'manila migration-complete' ." msgid "Confirm Migration Cancelling of Share" msgstr "Bestätige Abbruch der Migration einer Freigabe" msgid "Confirm Migration Completion of Share" msgstr "Bestätige Abschluss der Migration der Freigabe" msgid "Confirm Obtaining migration progress of Share" msgstr "Bestätige Erhalt des Migrationsfortschritts einer Freigabe" msgid "Confirm Password" msgstr "Bestätige Passwort" msgid "Confirm Unmanage Share" msgstr "Bestätige aufheben der Verwaltung einer Freigabe" msgid "Create" msgstr "Erstellen" msgid "Create Group Share Type" msgstr "Gruppenfreigabe-Typ erstellen" msgid "Create Replica" msgstr "Erstelle Replika" msgid "Create Security Service" msgstr "Erstelle Sicherheitsdienst" msgid "Create Share" msgstr "Freigabe erstellen" msgid "Create Share Group" msgstr "Freigabegruppe erstellen" msgid "Create Share Group Snapshot" msgstr "Freigabegruppe Schattenkopie erstellen" msgid "Create Share Group Type" msgstr "Freigabengruppe Typ erstellen" msgid "Create Share Network" msgstr "Erstelle Freigabenetzwerk" msgid "Create Share Replica" msgstr "Erstellen Share-Replikat" msgid "Create Share Snapshot" msgstr "Erstelle Fraigaben-Schattenkopie" msgid "Create Share Type" msgstr "Erstelle Freigabetyp" msgid "Create a Share" msgstr "Erstelle eine Freigabe" msgid "Create share replica in specific availability zone." msgstr "" "Erstellen Sie ein Share-Replikat in einer bestimmten Verfügbarkeitszone." msgid "Created" msgstr "Erstellt" msgid "Created At" msgstr "Erstellt um" msgid "Created At:" msgstr "Erstellt um:" msgid "Created at" msgstr "Erstellt am" msgctxt "Current status of replica" msgid "Creating" msgstr "Erstellen" msgctxt "Current status of share" msgid "Creating" msgstr "Erstellen" msgctxt "Current status of share server" msgid "Creating" msgstr "Erstellen" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Erstellen" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Erstelle Replika für Freigabe \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Erstelle Regel für \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Erstelle Freigabe \"%s\"" #, python-format msgid "Creating share group \"%s\"" msgstr "Erstelle Freigabegruppe \"%s\"" #, python-format msgid "Creating share group snapshot \"%s\"." msgstr "Gruppenfreigabe Schattenkopie \"%s\" erstellen." #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Erstelle geteilte Schattenkopie \"%s\"." #, python-format msgid "Creating snapshot rule for \"%s\"" msgstr "Erstelle Schattenkopie-Regel für \"%s\"" msgid "Current Size (GiB)" msgstr "Aktuelle Größe (GiB)" msgid "DNS IP" msgstr "DNS IP" msgid "Delete Replica" msgid_plural "Delete Replicas" msgstr[0] "Replik entfernen" msgstr[1] "Repliken entfernen" msgid "Delete Rule" msgid_plural "Delete Rules" msgstr[0] "Regel löschen" msgstr[1] "Regeln löschen" msgid "Delete Security Service" msgid_plural "Delete Security Services" msgstr[0] "Lösche Sicherheitsdienst" msgstr[1] "Lösche Sicherheitsdienste" msgid "Delete Share" msgid_plural "Delete Shares" msgstr[0] "Lösche Freigabe" msgstr[1] "Lösche Freigaben" msgid "Delete Share Group" msgid_plural "Delete Share Groups" msgstr[0] "Gruppenfreigabe löschen" msgstr[1] "Gruppenfreigaben löschen" msgid "Delete Share Group Snapshot" msgid_plural "Delete Share Group Snapshots" msgstr[0] "Freigabengruppe Schattenkopie löschen" msgstr[1] "Freigabengruppe Schattenkopien löschen" msgid "Delete Share Group Type" msgid_plural "Delete Share Group Types" msgstr[0] "Freigabengruppe Typ löschen" msgstr[1] "Freigabengruppen Typen löschen" msgid "Delete Share Network" msgid_plural "Delete Share Networks" msgstr[0] "Freigabenetzwerk löschen" msgstr[1] "Freigabenetzwerke löschen" msgid "Delete Share Server" msgid_plural "Delete Share Server" msgstr[0] "Freigabeserver entfernen" msgstr[1] "Freigabeserver entfernen" msgid "Delete Share Snapshot" msgid_plural "Delete Share Snapshots" msgstr[0] "Lösche Freigabeschattenkopie" msgstr[1] "Lösche Freigabeschattenkopien" msgid "Delete Share Snapshot Rule" msgid_plural "Delete Share Snapshot Rules" msgstr[0] "Lösche Regel Freigabeschattenkopie" msgstr[1] "Lösche Regeln Freigabeschattenkopie" msgid "Delete Share Type" msgid_plural "Delete Share Types" msgstr[0] "Freigabetyp löschen" msgstr[1] "Freigabetypen löschen" msgid "Delete Snapshot" msgid_plural "Delete Snapshots" msgstr[0] "Schattenkopie löschen" msgstr[1] "Schattenkopien löschen" msgid "Deleted Replica" msgid_plural "Deleted Replicas" msgstr[0] "Gelöschte Replik" msgstr[1] "Gelöschte Repliken" msgid "Deleted Rule" msgid_plural "Deleted Rules" msgstr[0] "Gelöschte Regel" msgstr[1] "Gelöschte Regeln" msgid "Deleted Security Service" msgid_plural "Deleted Security Services" msgstr[0] "Gelöschter Sicherheitsdienst" msgstr[1] "Gelöschte Sicherheitsdienste" msgid "Deleted Share" msgid_plural "Deleted Shares" msgstr[0] "Gelöschte Freigabe" msgstr[1] "Gelöschte Freigaben" msgid "Deleted Share Group" msgid_plural "Deleted Share Groups" msgstr[0] "Gelöschte Gruppenfreigabe" msgstr[1] "Gelöschte Gruppenfreigaben" msgid "Deleted Share Group Snapshot" msgid_plural "Deleted Share Group Snapshots" msgstr[0] "Gelöschte Freigabengruppe Schattenkopie" msgstr[1] "Gelöschte Freigabengruppe Schattenkopien" msgid "Deleted Share Group Type" msgid_plural "Deleted Share Group Types" msgstr[0] "Gelöschter Freigabengruppe Typ" msgstr[1] "Gelöschte Freigabengruppen Typen" msgid "Deleted Share Network" msgid_plural "Deleted Share Networks" msgstr[0] "Gelöschtes Freigabenetzwerk" msgstr[1] "Gelöschte Freigabennetzwerke" msgid "Deleted Share Server" msgid_plural "Deleted Share Server" msgstr[0] "Gelöschter Freigabeserver" msgstr[1] "Gelöschte Freigabeserver" msgid "Deleted Share Snapshot" msgid_plural "Deleted Share Snapshots" msgstr[0] "Freigabe Schattenkopie löschen" msgstr[1] "Freigabe Schattenkopien löschen" msgid "Deleted Share Snapshot Rule" msgid_plural "Deleted Share Snapshot Rules" msgstr[0] "Gelöschte Regeln Freigabeschattenkopie" msgstr[1] "Gelöschte Regeln Freigabeschattenkopie" msgid "Deleted Share Type" msgid_plural "Deleted Share Types" msgstr[0] "Gelöschter Freigabetyp" msgstr[1] "Gelöschte Freigabetypen" msgid "Deleted Snapshot" msgid_plural "Deleted Snapshots" msgstr[0] "Schattenkopie löschen" msgstr[1] "Schattenkopien löschen" msgctxt "Current status of replica" msgid "Deleting" msgstr "Löschen" msgctxt "Current status of share" msgid "Deleting" msgstr "Löschen" msgid "Description" msgstr "Beschreibung" msgid "Description:" msgstr "Beschreibung:" msgid "Destination host and pool where share will be migrated to." msgstr "Zielhost und Pool, zu dem die Shares migriert werden." msgid "Domain" msgstr "Domäne" msgid "Driver handles share servers" msgstr "Treiberhändler des Freigabeservers" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Treiberoptionen ('volume_id' für generischen Treiber, etc...)" #, python-format msgid "Duplicated keys '%s'." msgstr "Doppelte Schlüssel '%s'." msgid "Edit" msgstr "Bearbeiten" msgid "Edit Security Service" msgstr "Bearbeite Sicherheitsdienst" msgid "Edit Share" msgstr "Freigabe bearbeiten" msgid "Edit Share Metadata" msgstr "Freigabemetadaten bearbeiten" msgid "Edit Share Network" msgstr "Bearbeite Freigabenetzwerk" msgid "Edit Share Snapshot" msgstr "Freigabe Schattenkopie bearbeiten" msgid "Edit Share network" msgstr "Bearbeite Freigabenetzwerk" msgid "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgstr "" "Erzwingt die Migration der Share-Schattenkopien zum Ziel. Wenn aktiviert, " "wird die Host-gestützte Migration nicht verwendet." msgid "" "Enforces migration to be nondisruptive. If set to True, host-assisted " "migration will not be attempted." msgstr "" "Erzwingt unterbrechungsfreie Migration. Wenn aktiviert, wird die Host-" "gestützte Migration ausgelassen." msgid "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgstr "" "Erzwingt, dass bei der Migration die Shares schreibbar bleiben, während " "deren Inhalt bewegt wird. Wenn aktiviert, wird die Host-gestützte Migration " "ausgelassen." msgid "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgstr "" "Erzwingt, dass bei der Migration alle Datei-Metadaten bewahrt werden, " "während der Inhalt verschoben wird. Wenn aktiviert, wird die Host-gestützte " "Migration ausgelassen." msgid "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimizations." msgstr "" "Erzwingt die Verwendung der Host-gestützten Migration, welche " "Treiberoptimierungen umgeht." msgctxt "Current status of replica" msgid "Error" msgstr "Fehler" msgctxt "Current status of share" msgid "Error" msgstr "Fehler" msgctxt "Current status of share network" msgid "Error" msgstr "Fehler" msgctxt "Current status of share server" msgid "Error" msgstr "Fehler" msgctxt "Current status of snapshot" msgid "Error" msgstr "Fehler" msgid "Expected only pairs of key=value." msgstr "Erwartet nur Schlüssel=Wert Paare." msgid "Export location" msgstr "Exportiere Lokation" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "" "Exportiere Lokation der Freigabe. Beispiel für NFS: 1.2.3.4:/path/to/share" msgid "Export locations" msgstr "Lokationen exportieren" msgctxt "Current status of share" msgid "Extending Error" msgstr "Erweiterungsfehler" msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "Extra Spezifikation 'driver_handles_share_servers' ist erforderlich und " "sollte einen boolschen Wert haben." msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "Extra Spezifikation 'driver_handles_share_servers' ist erforderlich und " "sollte einen boolschen Wert haben." msgid "Extra specs" msgstr "Extra Spezifikationen" msgid "Force Host Assisted Migration" msgstr "Erzwinge durch Host unterstützte Migration" msgid "From here you can modify name and description of a security service." msgstr "" "Von hier aus können Sie den Namen und die Beschreibung eines " "Sicherheitsdienstes ändern." msgid "" "From here you can modify name and description of a share group snapshot." msgstr "" "Von hier aus können Sie den Namen und die Beschreibung eines " "Freigabengruppen-Schattenkopie ändern." msgid "From here you can modify name and description of a share network." msgstr "" "Hier können Sie Name und Beschreibung eines Freigabe-Netzwerkes ändern." msgid "From here you can modify name and description of a snapshot." msgstr "Hier können Sie Name und Beschreibung einer Schattenkopie ändern." msgid "" "From here you can modify name, description and visibility of a share group." msgstr "" "Von hier aus können Sie den Namen, Beschreibung und Sichtbarkeit eier " "Freigabegruppe ändern." msgid "From here you can modify name, description and visibility of a share." msgstr "" "Hier können Sie Name, Beschreibung und Sichtbarkeit einer Freigabe ändern." msgid "From here you can revert the share to its latest snapshot." msgstr "" "Hier können Sie die Freigabe auf die letzte Schattenkopie zurücksetzen." msgid "From here you can update share network info. " msgstr "Hier können Sie Informationen zum Freigabenetzwerk aktualisieren." msgid "From here you can update the default share quotas (max limits)." msgstr "" "Von hier aus können Sie die Standard-Share-Kontingente (Höchstgrenzen) " "aktualisieren." msgid "Get Migration Progress" msgstr "Migrationsfortschritt abrufen" msgid "Get migration progress" msgstr "Migrationsfortschritt abrufen" msgid "GiB" msgstr "GiB" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "Falscher Wert für das Feld 'driver_options' erhalten. Erwartet werden nur " "Schlüssel=Wert Paare." msgid "Group specs" msgstr "Gruppenspezifikationen" msgid "Here can be modified extra-specs for share type." msgstr "" "Hier können Sie die Extra-Spezifikationen für Share-Typen modifizieren." msgid "Here can be modified group-specs for share group type." msgstr "" "Hier können Sie Gruppen-Spezifikationen für den Freigabegruppentyp ändern." msgid "Host" msgstr "Host" msgid "Host of share" msgstr "Host der Freigabe" msgid "Host to migrate share" msgstr "Host zur Migration der Freigabe" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "" "Host, auf dem die Freigabe beheimatet ist, Beispiel: some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "ID:" msgstr "ID:" msgid "IP Version" msgstr "IP Version" msgid "Id" msgstr "Id" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "Falscher Wert zum Setzen der Extra Spezifikation " "'spec_driver_handles_share_servers'. Erlaubte Werte sind %s. Gross- und " "Kleinschreibung wird ignoriert." msgctxt "Current status of share server" msgid "In-use" msgstr "In Benutzung" msgctxt "Current status of snapshot" msgid "In-use" msgstr "In Benutzung" msgctxt "Current status of share network" msgid "Inactive" msgstr "Inaktiv" #, python-format msgid "Key '%s' has improper length." msgstr "Schlüssel '%s' hat die falsche Länge." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Der Schlüssel darf keine Leerzeichen enthalten. Prüfen Sie '%s'." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Schlüssel dürfen keine Leerzeichen enthalten. Fehler in '%s'." msgid "Limit" msgstr "Limit" msgid "Manage" msgstr "Verwalten" msgctxt "Current status of share" msgid "Manage Error" msgstr "Fehler verwalten" msgid "Manage Replicas" msgstr "Verwalte Replikas" msgid "Manage Rules" msgstr "Regeln verwalten" msgid "Manage Share" msgstr "Verwalte Freigabe" msgid "Manage Share Group Type Access" msgstr "Freigabengruppe Typzugriff verwalten" msgid "Manage Share Snapshot Rules" msgstr "Verwalte Regeln Freigabeschattenkopie" msgid "Manage Share Type Access" msgstr "Verwalte Freigabetypzugriff" msgid "Metadata" msgstr "Metadaten" msgid "Migrate Share" msgstr "Migriere Freigabe" msgid "Migrate a Share" msgstr "Freigabe migrieren" msgid "" "Migrate an existing share to another Manila host. This will move all your " "share data from one host to another.

This is equivalent to the " "'manila migration-start' command." msgstr "" "Migrieren Sie eine vorhandene Freigabe auf einen anderen Manila-Host. " "Dadurch werden alle Ihre Freigabedaten von einem Host auf einen anderen " "verschoben.

Dies entspricht dem Befehl 'manila migration-" "start' ." msgctxt "Current status of share" msgid "Migrating" msgstr "Migrieren" msgctxt "Current status of share" msgid "Migrating to" msgstr "Migriere nach" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "Migration der Freigabe %(name)s ist bei %(progress)s Prozent." msgid "Mount snapshot support" msgstr "Schattenkopie mount-Unterstützung" msgid "Name" msgstr "Name" msgid "Name:" msgstr "Name:" msgid "Net Details" msgstr "Netz Details" msgid "Network" msgstr "Netzwerk" msgid "Network Details" msgstr "Netzwerkdetails" msgid "Network Type" msgstr "Netzwerktyp" msgid "Networks" msgstr "Netzwerke" msgid "Neutron Net" msgstr "Neutron Netz" msgid "Neutron Subnet" msgstr "Neutron Subnetz" msgid "New Size (GiB)" msgstr "Neue Größe (GiB)" msgid "New share network to be set in migrated share" msgstr "Neues Freigabenetzwerk, um es in der migrierten Freigabe zu setzen." msgid "New share type to be set in migrating share" msgstr "Neuer Freigabetyp, um ihn in der migrierten Freigabe zu setzen" msgid "No projects found." msgstr "Keine Projekte gefunden." msgid "No projects selected." msgstr "Keine Projekte ausgewählt." msgid "No security services found." msgstr "Keine Sicherheitsdienste gefunden." msgid "No security services selected." msgstr "Keine Sicherheitsdienste ausgewählt." msgid "No source, empty share" msgstr "Keine Quelle, leere Freigabe" msgid "No source, empty share group" msgstr "Keine Quelle, leere Gruppenfreigabe" msgid "Nondisruptive" msgstr "Ohne Unterbrechung" msgid "Number of Share Snapshots" msgstr "Anzahl der Freigaben-Schattenkopien" msgid "Number of Shares" msgstr "Anzahl der Freigaben" msgid "Obtain Progress" msgstr "Erhalte Fortschritt" msgid "Obtain migration progress of a Share" msgstr "Erhalte Fortschritt der Migration einer Freigabe" msgid "" "Obtains migration progress of a migrating share.

This is " "equivalent to the 'manila migration-get-progress' command." msgstr "" "Ruft den Migrationsfortschritt einer migrierenden Freigabe ab.

" "Dies entspricht dem Befehl 'manila migration-get-progress' ." msgid "One line - one action. Empty strings will be ignored." msgstr "Eine Zeile - eine Aktion. Leere Zeichenketten werden ignoriert." msgid "Overview" msgstr "Übersicht" msgid "Password" msgstr "Passwort" msgid "Passwords do not match." msgstr "Passwörter stimmen nicht überein." msgid "Path:" msgstr "Pfad:" msgid "Placeholder for description of share group type access managing form." msgstr "Platzhalter für Beschreibung der Share-Gruppentypen-Verwaltungsform." msgid "Placeholder for description of share type access managing form." msgstr "Platzhalter für Beschreibung der Share-Typen-Verwaltungsform." msgid "Preserve Metadata" msgstr "Metadaten behalten" msgid "Preserve Snapshots" msgstr "Schattenkopien aufbewahren" msgid "Project" msgstr "Projekt" msgid "Projects with access to share group type" msgstr "Projekte mit Zugriff auf Gruppenfreigabetypen" msgid "Projects with access to share type" msgstr "Projekte mit Zugriff auf Freigabetypen" msgid "Protocol" msgstr "Protokoll" msgid "Public" msgstr "Öffentlich" msgid "Quota Name" msgstr "Kontingentname" msgid "Replica Details" msgstr "Replika Details" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Replika Details: %(replica_display_name)s" msgid "Replica State" msgstr "Replika Zustand" msgid "Replica state" msgstr "Replika Zustand" msgid "Replicas" msgstr "Replikas" msgid "Reset Replica State" msgstr "Replika Zustand zurücksetzen" msgid "Reset Replica Status" msgstr "Replika Status zurücksetzen" msgid "Reset Share Group Snapshot Status" msgstr "Rücksetzung des Status der Schattenkopie der Gruppenfreigabe" msgid "Reset Share Group Status" msgstr "Gruppenfreigaben Status zurücksetzen" msgid "Reset Status" msgstr "Status zurücksetzen" msgid "Reset replica state" msgstr "Replika Zustand zurücksetzen" msgid "Reset replica status" msgstr "Replika-Status zurücksetzen" msgid "Reset share replica's state with ID" msgstr "Freigabe-Replika Zustand mit ID zurücksetzen" msgid "Reset share replica's status with ID" msgstr "Freigabe-Replika Status mit ID zurücksetzen" msgid "Reset state" msgstr "Zustand zurücksetzen" msgid "Reset status" msgstr "Status zurücksetzen" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "" "Setze Status von Replika ('%(id)s') von '%(from)s' auf '%(to)s' zurück." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Zurücksetzen des Status von Replika ('%(id)s') von '%(from)s' zu '%(to)s'." #, python-format msgid "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Gruppenfreigabe ('%(id)s') Status zurücksetzen von '%(from)s' zu '%(to)s'." #, python-format msgid "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Rücksetzung der Schattenkopie der Freigabegruppe ('%(id)s') Status von " "'%(from)s' zu '%(to)s'." msgid "Resync" msgstr "Resynchronisieren" msgid "Resync Replica" msgstr "Resynchronisiere Replika" msgid "Resync replica" msgstr "Resynchronisiere Replika" msgid "Resync share replica with ID" msgstr "Resync der Freigabe-Replica mit ID" #, python-format msgid "Resync'ing replica '%s'" msgstr "Resynchronisiere Replika '%s'" msgid "Revert Share" msgstr "Freigabe zurückstellen" msgid "Revert Share to a Snapshot" msgstr "Share auf Schattenkopie zurücksetzen" msgid "Revert share to a snapshot" msgstr "Freigabe auf Schattenkopie zurückstellen" msgctxt "Current status of share" msgid "Reverting Error" msgstr "Fehler beim Zurückstellen" msgid "Rules" msgstr "Regeln" msgid "Save Changes" msgstr "Änderungen speichern" msgid "Security Service Details" msgstr "Sicherheitsdienstdetails" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Sicherheitsdienst-Details: %(service_display_name)s" msgid "Security Service Overview" msgstr "Sicherheitsdienst Überblick" msgid "Security Services" msgstr "Sicherheitsdienste" msgid "Security services within share network" msgstr "Sicherheitsdienste in Freigabenetzwerk" msgid "Segmentation Id" msgstr "Segmentierungs-ID" msgid "Select parameters of share group you want to create. " msgstr "" "Wählen Sie die Parameter der Freigabegruppe, die Sie erstellen möchten." msgid "Select parameters of share you want to create. " msgstr "Wählen Sie die Parameter der Freigabe, die Sie erstellen möchten." msgid "Selected Networks" msgstr "Ausgewählte Netzwerke" msgid "Selected Projects" msgstr "Ausgewählte Projekte" msgid "Selected projects" msgstr "Ausgewählte Projekte" msgid "Selected security services" msgstr "Gewählte SIcherheitsdienste" msgid "Server" msgstr "Server" msgid "Set Replica as Active" msgstr "Setze Replika auf aktiv" msgid "Set as Active" msgstr "Setze auf aktiv" msgid "Set maximum quotas for the project." msgstr "Setze maximale Kontingente für dieses Projekt." msgid "Set share replica with ID" msgstr "Setzen des Share-Replikat mit ID" #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Setze Replika \"%s\" auf aktiv..." msgid "Share" msgstr "Freigabe" #, python-format msgid "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgstr "Freigabe \"%(s)s\" wurde auf Schattenkkopie \"%(ss)s\" zurückgestellt" msgid "Share Details" msgstr "Freigabendetails" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Details Freigabe: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Freigabedetails: %(share_name)s" msgid "Share Group" msgstr "Freigabegruppe" msgid "Share Group Details" msgstr "Freigabegruppe Details" #, python-format msgid "Share Group Details: %s" msgstr "Gruppenfreigaben Details: %s" msgid "Share Group Name" msgstr "Freigabegruppe Name" msgid "Share Group Overview" msgstr "Gruppenfreigabe Übersicht" msgid "Share Group Snapshot" msgstr "Freigabegruppe Schattenkopie" msgid "Share Group Snapshot Details" msgstr "Share Gruppe Schattenkopiedetails" #, python-format msgid "Share Group Snapshot Details: %(sgs_display_name)s" msgstr "Details der Schattenkopie der Gruppenfreigabe: %(sgs_display_name)s" msgid "Share Group Snapshot Overview" msgstr "Übersicht der Schattenkopien der Freigabegruppen" msgid "Share Group Snapshots" msgstr "Freigabengruppe Schattenkopien" msgid "Share Group Type" msgstr "Gruppenfreigabetyp" msgid "Share Group Types" msgstr "Freigabengruppe Typen" msgid "Share Groups" msgstr "Gruppenfreigaben" msgid "Share ID" msgstr "Freigabe-ID" msgid "Share Instance Details" msgstr "Freigabeinstanz Details" #, python-format msgid "Share Instance Details: %s" msgstr "Details Freigabeinstanz: %s" msgid "Share Instance Overview" msgstr "Freigegebene Instanzen Übersicht" msgid "Share Instances" msgstr "Freigabeinstanzen" msgid "Share Limits" msgstr "Freigabenlimits" msgid "Share Name" msgstr "Freigabename" msgid "Share Network" msgstr "Freigabenetzwerk" msgid "Share Network Details" msgstr "Freigabenetzwerk Details" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Details Freigabenetzwerk: %(network_display_name)s" msgid "Share Network Info" msgstr "Freigabenetzwerk Informationen" msgid "Share Network Overview" msgstr "Freigabenetzwerke Übersicht" msgid "Share Networks" msgstr "Freigabenetzwerke" msgid "Share Overview" msgstr "Freigaben Übersicht" msgid "Share Protocol" msgstr "Freigabenprotokoll" msgid "Share Quotas" msgstr "Kontingente teilen" msgid "Share Replica Overview" msgstr "Freigabe-Replikaübersicht" msgid "Share Replicas" msgstr "Freigaben-Replikas" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Freigaben-Replikas: %(share_display_name)s" msgid "Share Rules" msgstr "Freigabenregeln" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Freigaberegeln: %(share_display_name)s" msgid "Share Server" msgstr "Freigabeserver" msgid "Share Server Details" msgstr "Freigabeserver Details" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Details Freigabeserver: %(server_name)s" msgid "Share Server Id" msgstr "Freigabeserver-ID" msgid "Share Server Overview" msgstr "Freigabeserver Übersicht" msgid "Share Servers" msgstr "Freigabeserver" msgid "Share Snapshot Details" msgstr "Details Freigabe-Schattenkopie" msgid "Share Snapshot Name" msgstr "Freigegebene Schattenkopie Name" msgid "Share Snapshot Overview" msgstr "Schattenkopieübersicht teilen" msgid "Share Snapshot Rules" msgstr "Schattenkopie-Regeln löschen" msgid "Share Snapshots" msgstr "Freigabe Schattenkopien" msgid "Share Snapshots Storage" msgstr "Freigabe Schattenkopienspeicher" msgid "" "Share Snapshots are used for storing share changes and creating shares. " msgstr "" "Freigabe Schattenkopien werden benutzt zum Speichern von Freigabeänderungen " "und Freigabeerstellungen." msgid "Share Source" msgstr "Freigabequelle" msgid "Share Storage" msgstr "Freigabespeicher" msgid "Share Type" msgstr "Freigabetyp" msgid "Share Types" msgstr "Freigabetypen" msgid "Share Types (multiple available)" msgstr "Freigabetypen (mehrere verfügbar)" msgid "Share Types (one available)" msgstr "Freigabetypen (eine verfügbar)" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Die Freigabe kann nicht auf %(req)iGiB erweitert werden, da nur %(avail)iGiB " "in Ihrem Kontingent verfügbar sind." msgid "Share gigabytes" msgstr "Freigabe Gigabyte" msgid "Share name to be assigned" msgstr "Zuzuweisender Freigabename" msgid "Share network" msgstr "Freigabenetzwerk" msgid "" "Share networks contain network data, that will be used for creation of " "service VM, where will be hosted shares." msgstr "" "Share-Netzwerke enthalten Netzwerkdaten, die für die Erstellung von Service-" "VMs verwendet werden, auf denen gehostete Shares gespeichert werden." #, python-format msgid "Share replica %s has been deleted." msgstr "Freigabe Replika %s wurde gelöscht." msgid "Share server" msgstr "Freigabeserver" #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "" "Freigabegrösse muss gleich oder grösser als die Grösse der Schattenkopie " "sein (%sGiB)" msgid "Share snapshot gigabytes" msgstr " Freigabeschattenkopie gigabytes" msgid "Share snapshots" msgstr " Freigabeschattenkopien" msgid "Share type" msgstr "Freigabetyp" msgid "Share types" msgstr "Freigabetypen" msgid "Shared Quotas" msgstr "Geteilte Kontingente" msgid "Shares" msgstr "Freigaben" msgid "Shares on this server" msgstr "Freigaben auf diesem Server" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Grösse" msgid "Size (GiB)" msgstr "Grösse (GiB)" msgid "Snapshot" msgstr "Schattenkopie" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Schattenkopiedetails: %(snapshot_display_name)s" msgid "Snapshot ID" msgstr "Schattenkopie ID" msgid "Snapshot Overview" msgstr "Übersicht Schattenkopie" #, python-format msgid "Snapshot Rules: %(snapshot_display_name)s" msgstr "Schattenkopie-Regeln: %(snapshot_display_name)s" msgid "Source" msgstr "Quelle" msgid "Source SG Snapshot" msgstr "Quelle SG Schattenkopie" msgid "Source Share Group" msgstr "Quellen Share Gruppe" msgid "Source Share Group Snapshot" msgstr "Quelle Schattenkopie Gruppenfreigabe" msgid "Source Type" msgstr "Quellentyp" msgid "Source share group snapshot" msgstr "Quelle Schattenkopie Gruppenfreigabe" msgid "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgstr "" "Geben Sie das neue Share-Netzwerk für das Share an. Geben Sie diesen " "Parameter nicht an, wenn das Migrations-Share im aktuellen Share-Netzwerk " "verbleiben soll." msgid "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgstr "" "Geben Sie den neuen Share-Typ für das Share an. Geben Sie diesen Parameter " "nicht an, wenn das Migrations-Share seinen aktuellen Share-Typ behalten soll." msgid "Specs" msgstr "Spezifikationen" msgid "Start migration" msgstr "Migration starten" msgid "Status" msgstr "Status" msgid "Status:" msgstr "Status:" msgid "Submit" msgstr "Absenden" msgid "Subnet" msgstr "Subnetz" #, python-format msgid "Successfully created security service: %s" msgstr "Sicherheitsdienst erfolgreich erstellt: %s" #, python-format msgid "Successfully created share group type: %s" msgstr "Gruppenfreigabe Typ erfolgreich erstellt: %s" #, python-format msgid "Successfully created share network: %s" msgstr "Freigabenetzwerk erfolgreich erstellt: %s" #, python-format msgid "Successfully created share type: %s" msgstr "Freigabetyp erfolgreich erstellt: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "" "Anfrage zum Abbruch der Migration der Freigabe erfolgreich gesendet: %s" #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "" "Anfrage zum Abschließen der Migration der Freigabe erfolgreich gesendet: %s" #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Anfrage zur Verwaltung der Freigabe erfolgreich gesendet: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "Anfrage zur Migration der Freigabe erfolgreich gesendet: %s" #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "" "Anfrage zum Aufheben der Verwaltung der Freigabe erfolgreich gesendet: %s" #, python-format msgid "Successfully updated group specs for share group type '%s'." msgstr "Spezifikationen für Gruppenfreigabe Typ '%s' erfolgreich aktualisiert." #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Erfolgreiche Aktualisierung des Sicherheitsdienstes \"%s\"" msgid "Task state" msgstr "Auftragsstatus" msgid "" "The security service can be used by backend drivers to configure clients, " "for more secure using of share." msgstr "" "Der Sicherheitsdienst kann von Back-End-Treibern zum Konfigurieren von " "Clients verwendet werden, um die Verwendung von Freigabe sicherer zu machen." msgid "" "The share group type defines the characteristics of a share group backend." msgstr "" "Der Share-Gruppentyp definiert die Merkmale eines Back-End-Share-Gruppe." #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "" "Die Größe der Freigabe kann nicht kleiner als die der Schattenkopie sein " "(%sGiB)" msgid "The share type defines the characteristics of a share backend." msgstr "Der Share-Typ definiert die Merkmale eines Share-Backends." msgid "To add extra-specs use:" msgstr "Zum hinzufügen von extra-Spezifikationen verwenden Sie:" msgid "To add group-specs use:" msgstr "Zum Hinzufügen von group-specs benutzen Sie:" msgid "To add metadata use:" msgstr "Zum hinzufügen von Metadaten verwenden Sie:" msgid "To unset extra-specs use:" msgstr "Zum Zurücksetzen von Extraspezifikationen verwenden Sie:" msgid "To unset group-specs use:" msgstr "Zum zurücksetzen von Gruppen-Spezifikationen verwenden Sie:" msgid "To unset metadata use:" msgstr "Zum Zurücksetzen von Metadaten verwenden Sie:" msgid "Total Gibibytes" msgstr "Gesamt Gibibytes" msgid "Type" msgstr "Typ" msgid "Unable to add rule." msgstr "Konnte Regel nicht hinzufügen." msgid "Unable to add snapshot rule." msgstr "Schattenkopie-Regel kann nicht hinzugefügt werden." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "Kann Migration der Freigabe %s momentan nicht abbrechen." #, python-format msgid "Unable to complete migration of share %s." msgstr "Konnte Migration der Freigabe %s nicht fertigstellen." msgid "Unable to create security service." msgstr "Konnte Sicherheitsdienst nicht erstellen." msgid "Unable to create share group snapshot." msgstr "Konnte Schattenkopie von Gruppenfreigabe nicht erstellen." msgid "Unable to create share group type." msgstr "Gruppenfreigabe Typ kann nicht erstellt werden." msgid "Unable to create share group." msgstr "Konnte Gruppenfreigabe nicht erstellen." msgid "Unable to create share network." msgstr "Konnte Freigabenetzwerk nicht erstellen." msgid "Unable to create share replica." msgstr "Konnte Freigabe-Replika nicht erstellen." msgid "Unable to create share snapshot." msgstr "Konnte Freigaben-Schattenkopie nicht erstellen." msgid "Unable to create share type." msgstr "Konnte Freigabetyp nicht erstellen." msgid "Unable to create share." msgstr "Konnte Freigabe nicht erstellen." #, python-format msgid "Unable to create share. %s" msgstr "Freigabe kann nicht erstellt werden. %s" #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Konnte Replika \"%s\" nicht löschen." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Konnte Regel \"%s\" nicht löschen." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Konnte Freigabe \"%s\" nicht löschen." #, python-format msgid "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." msgstr "" "Konnte die Schattenkopie \"%s\" der Freigabegruppe nicht löschen. Eine oder " "mehre Freigabegruppen hängen davon ab." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "Konnte Schattenkopie \"%s\" nicht löschen. Eine oder mehrere Freigaben sind " "davon abhängig." #, python-format msgid "Unable to delete snapshot rule \"%s\"." msgstr "Schattenkopie-Regel \"%s\" kann nicht gelöscht werden." msgid "Unable to get information about share group type access." msgstr "" "Informationen über den Zugriff auf Gruppenfreigaben können nicht abgerufen " "werden." msgid "Unable to get information about share type access." msgstr "Konnte Informationen über Freigabetypenzugriff nicht abrufen." msgid "Unable to get list of projects." msgstr "Konnte Projektliste nicht abrufen." msgid "Unable to get manila default quota." msgstr "Manila-Standardkontingent kann nicht abgerufen werden." msgid "Unable to get the security services hosts" msgstr "Konnte die Sicherheitsdienst-Hosts nicht abrufen" #, python-format msgid "Unable to get the specified share group '%s' for snapshot creation." msgstr "" "Konnte die Spezifikationen zur Gruppenfreigabe '%s' für " "Schattenkopieerstellung nicht empfangen." msgid "Unable to load the specified share group snapshot." msgstr "Konnte spezifizierte Schattenkopie der Gruppenfreigabe nicht laden." msgid "Unable to load the specified snapshot." msgstr "Konnte angegebene Schattenkopie nicht laden." msgid "Unable to manage share" msgstr "Konnte Freigabe nicht verwalten" #, python-format msgid "Unable to migrate share %s." msgstr "Konnte Freigabe %s nicht migrieren." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "" "Kann den Fortschritt der Migration der Freigaben %s momentan nicht abrufen." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "Konnte Status des Replika %s nicht zurücksetzen." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "Konnte Status des Replika %s nicht zurücksetzen." #, python-format msgid "Unable to reset status of share group '%s'." msgstr "Status der Gruppenfreigabe '%s' kann nicht zurückgesetzt werden." #, python-format msgid "Unable to reset status of share group snapshot '%s'." msgstr "Konnte die Schattenkopie '%s' der Freigabegruppe nicht zurücksetzen." #, python-format msgid "Unable to resync replica '%s'." msgstr "Resynchronisieren von Replika '%s' nicht möglich ." msgid "Unable to retrieve default share quotas." msgstr "Standard-Freigaben-Kontingente können nicht abgerufen werden." #, python-format msgid "Unable to retrieve details of replica %s" msgstr "Konnte Details der Replika '%s' nicht abrufen" msgid "Unable to retrieve list of projects." msgstr "Konnte Projektliste nicht abrufen" msgid "Unable to retrieve quotas." msgstr "Konnte Kontingente nicht abrufen." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Konnte Replika '%s' nicht abrufen." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Konnte Details zu Sicherheitsdienst '%s' nicht abrufen." msgid "Unable to retrieve security services" msgstr "Konnte Sicherheitsdienste nicht abrufen" msgid "Unable to retrieve security_service." msgstr "Konnte Sicherheitsdienst nicht abrufen." msgid "Unable to retrieve share details." msgstr "Konnte Freigabendetails nicht abrufen." #, python-format msgid "Unable to retrieve share group '%s'." msgstr "Gruppenfreigabe '%s' kann nicht abgerufen werden." msgid "Unable to retrieve share group details." msgstr "Gruppenfreigaben Details können nicht abgerufen werden." #, python-format msgid "Unable to retrieve share group snapshot '%s'." msgstr "Freigabengruppe Schattenkopie '%s' kann nicht abgerufen werden." msgid "Unable to retrieve share group snapshot details." msgstr "" "Konnte die Details der Schattenkopie der Gruppenfreigabe nicht abrufen." msgid "Unable to retrieve share group snapshot list." msgstr "Konnte die Liste der Schattenkopien der Freigabegruppen nicht abrufen." msgid "Unable to retrieve share group snapshot." msgstr "Konnte Schattenkopie der Gruppenfreigabe nicht empfangen." msgid "Unable to retrieve share group snapshots." msgstr "Konnte Schattenkopien der Gruppenfreigabe nicht empfangen." msgid "Unable to retrieve share group types." msgstr "Freigabengruppe Typen können nicht abgerufen werden." msgid "Unable to retrieve share group." msgstr "Konnte Gruppenfreigabe nicht abrufen" msgid "Unable to retrieve share groups." msgstr "Gruppenfreigaben können nicht abgerufen werden." msgid "Unable to retrieve share instance details." msgstr "Konnte Freigabeinstanzdetails nicht abrufen." msgid "Unable to retrieve share instances." msgstr "Konnte Freigabeinstanzen nicht abrufen" msgid "Unable to retrieve share limit information." msgstr "Konnte Informationen zu Freigabenlimits nicht abrufen." msgid "Unable to retrieve share list." msgstr "Konnte Liste der Freigaben nicht abrufen" msgid "Unable to retrieve share network details." msgstr "Konnte Details zum Freigabenetzwerk nicht abrufen." msgid "Unable to retrieve share network." msgstr "Konnte Freigabenetzwerk nicht abrufen." msgid "Unable to retrieve share networks" msgstr "Konnte Freigabenetzwerke nicht abrufen" msgid "Unable to retrieve share quotas." msgstr "Freigaben-Kontingente können nicht abgerufen werden." msgid "Unable to retrieve share replicas." msgstr "Konnte Freigaben-Replikas nicht abrufen." msgid "Unable to retrieve share rules." msgstr "Konnte Freigaberegeln nicht abrufen." msgid "Unable to retrieve share server details." msgstr "Konnte Details zum Freigabeserver nicht abrufen." msgid "Unable to retrieve share servers" msgstr "Konnte Freigabeserver nicht abrufen" msgid "Unable to retrieve share snapshot list." msgstr "Konnte Liste der geteilten Schattenkopien nicht abrufen." msgid "Unable to retrieve share snapshot rules." msgstr "Konnte Regeln für Freigabeschattenkopie nicht abrufen." msgid "Unable to retrieve share snapshot." msgstr "Konnte Freigabeschattenkopie nicht abrufen." msgid "Unable to retrieve share snapshots list." msgstr "Konnte Freigaben-Schattenkopieliste nicht abrufen." msgid "Unable to retrieve share snapshots." msgstr "Konnte freigegebene Schattenkopien nicht abrufen." msgid "Unable to retrieve share types." msgstr "Freigabetypen können nicht abgerufen werden." msgid "Unable to retrieve share." msgstr "Konnte Freigabe nicht abrufen." #, python-format msgid "Unable to retrieve share. %s" msgstr "Konnte Freigabe nicht abrufen. %s" msgid "Unable to retrieve share_gruop_type." msgstr "Konnte share_gruop_type nicht abrufen." msgid "Unable to retrieve share_type." msgstr "Konnte den Freigabetyp nicht abrufen." msgid "Unable to retrieve snapshot details." msgstr "Konnte Schattenkopiedetails nicht abrufen." msgid "Unable to retrieve snapshot." msgstr "Konnte Schattenkopie nicht abrufen." msgid "Unable to retrieve volume details." msgstr "Konnte Datenträgerdetails nicht abrufen." msgid "Unable to revert share to the snapshot." msgstr "Freigabe kann nicht auf Schattenkopie zurückgestellt werden." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Konnte Replika \"%s\" nicht auf aktiv setzen." msgid "Unable to unmanage share." msgstr "Konnte Verwaltung der Freigabe nicht aufheben" #, python-format msgid "Unable to update access for share group type \"%s\"." msgstr "" "Zugriff zum Gruppenfreigabetyp \"%s\" konnte nicht aktualisiert werden." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Konnte Zugriff für Freigabetyp \"%s\" nicht aktualisieren." msgid "Unable to update default quotas." msgstr "Konnte Standardkontingente nicht aktualisieren." msgid "Unable to update group_specs for share group type." msgstr "" "Spezifikationen für Gruppenfreigabe Typ können nicht aktualisiert werden." msgid "Unable to update security service." msgstr "Konnte Sicherheitsdienst nicht aktualisieren." msgid "Unable to update share group snapshot." msgstr "Freigabegruppe Schattenkopie kann nicht aktualisiert werden." msgid "Unable to update share group type." msgstr "Gruppenfreigabetyp konnte nicht aktualisiert werden." msgid "Unable to update share group." msgstr "Konnte Gruppenfreigabe nicht aktualisieren." msgid "Unable to update share metadata." msgstr "Konnte Freigabe Metadaten nicht aktualisieren." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Konnte Freigabenetzwerk \"%s\" nicht aktualisieren." msgid "Unable to update share network." msgstr "Konnte Freigabenetzwerk nicht aktualisieren." msgid "Unable to update share snapshot." msgstr "Konnte Schattenkopie Gruppenfreigabe nicht aktualisieren." msgid "Unable to update share type." msgstr "Konnte Freigabetyp nicht aktualisieren." msgid "Unable to update share." msgstr "Konnte Freigabe nicht aktualisieren." msgid "Unknown" msgstr "Unbekannt" msgid "Unmanage" msgstr "Verwaltung aufheben" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Fehlerverwaltung aufheben" msgid "Unmanage Share" msgstr "Verwaltung der Freigabe aufheben" msgid "Update" msgstr "Aktualisieren" msgid "Update Share Group" msgstr "Freigabegruppe aktualisieren" msgid "Update Share Group Snapshot" msgstr "Freigabegruppe Schattenkopie aktualisieren" msgid "Update Share Group Type" msgstr "Freigabengruppe Typ aktualisieren" msgid "Update Share Network" msgstr "Aktualisiere Freigabenetzwerk" msgid "Update Share Snapshot" msgstr "Aktualisiere Freigabeschattenkopie" msgid "Update Share Type" msgstr "Aktualisiere Freigabetyp" msgid "Update Share group Type" msgstr "Freigabengruppe Typ aktualisieren" msgid "Update share network" msgstr "Aktualisiere Freigabenetzwerk" msgid "Updated" msgstr "Aktualisiert" msgid "Updated At" msgstr "Aktualisiert um" msgid "Updated At:" msgstr "Aktualisiert am:" #, python-format msgid "Updated access for share group type \"%s\"." msgstr "Zugriff zum Gruppenfreigabetyp aktualisiert \"%s\"." #, python-format msgid "Updated access for share type \"%s\"." msgstr "Zugriff für Freigabetyp \"%s\" aktualisiert." #, python-format msgid "Updated share network \"%s\"." msgstr "Aktualisiere Freigabenetzwerk \"%s\"." #, python-format msgid "Updating share \"%s\"" msgstr "Aktualisiere Freigabe \"%s\"" #, python-format msgid "Updating share group \"%s\"" msgstr "Aktualisiere Gruppenfreigabe \"%s\"" #, python-format msgid "Updating share group snapshot \"%s\"" msgstr "Gruppenfreigabe Schattenkopie \"%s\" wird aktualisiert." #, python-format msgid "Updating share metadata \"%s\"" msgstr "Aktualisiere Freigabe Metadaten \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Aktualisiere Freigabenetzwerk \"%s\"" #, python-format msgid "Updating share snapshot \"%s\"" msgstr "Aktualisiere Schattenkopie Gruppenfreigabe \"%s\"" msgid "Use share group snapshot as a source" msgstr "Benutze Gruppenfreigabe Schattenkopie als Quelle" msgid "Use snapshot as a source" msgstr "Benutze Schattenkopie als Quelle" msgid "User" msgstr "Benutzer" msgid "Visibility" msgstr "Sichtbarkeit" msgid "" "When a share is \"unmanaged\", the share will no longer be visible within " "OpenStack. Note that the share will not be deleted.

This is " "equivalent to the 'manila unmanage' command." msgstr "" "Wenn eine Freigabe \"nicht verwaltet\" ist, ist die Freigabe in OpenStack " "nicht mehr sichtbar. Beachten Sie, dass die Freigabe nicht gelöscht wird. " "

Dies entspricht dem Befehl 'manila unmanage' ." msgid "Writable" msgstr "Beschreibbar" msgid "as Active?" msgstr "als aktiv?" msgid "key=value pairs per line can be set" msgstr "Schlüssel=Wert Paare pro Zeile können gesetzt werden" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/en_GB/0000775000175000017500000000000000000000000017637 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/en_GB/LC_MESSAGES/0000775000175000017500000000000000000000000021424 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/en_GB/LC_MESSAGES/django.po0000664000175000017500000014500100000000000023227 0ustar00zuulzuul00000000000000# Andi Chandler , 2017. #zanata # Andi Chandler , 2018. #zanata # Andi Chandler , 2019. #zanata # Andi Chandler , 2020. #zanata # Andi Chandler , 2022. #zanata # Andi Chandler , 2023. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+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-08 11:41+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en_GB\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid " Share Type Visibility:" msgstr " Share Type Visibility:" msgid "" "\"Manage\" an existing share from a Manila host. This will make the share " "visible within OpenStack.

This is equivalent to the 'manila " "manage' command." msgstr "" "\"Manage\" an existing share from a Manila host. This will make the share " "visible within OpenStack.

This is equivalent to the 'manila " "manage' command." #, python-format msgid "%(used)s of %(quota)s GiB Used" msgstr "%(used)s of %(quota)s GiB Used" #, python-format msgid "%(used)s of %(quota)s Used" msgstr "%(used)s of %(quota)s Used" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(Quota exceeded)" msgid "Access Key" msgstr "Access Key" msgid "Access Key:" msgstr "Access Key:" msgid "Access Level" msgstr "Access Level" msgid "Access Level:" msgstr "Access Level:" msgid "Access Rules" msgstr "Access Rules" msgid "Access To" msgstr "Access To" msgid "Access Type" msgstr "Access Type" msgid "Access to" msgstr "Access to" msgid "Access to:" msgstr "Access to:" msgid "Action" msgstr "Action" msgctxt "Current status of share network" msgid "Active" msgstr "Active" msgctxt "Current status of share server" msgid "Active" msgstr "Active" msgid "Add" msgstr "Add" msgid "Add Rule" msgstr "Add Rule" msgid "Add Security Service" msgstr "Add Security Service" msgid "Add Share Snapshot Rule" msgstr "Add Share Snapshot Rule" msgid "" "Add policy rule to share, 'ip' rule represents IPv4 or IPv6 address, 'user' " "rule represents username or usergroup, 'cephx' rule represents ceph auth ID." msgstr "" "Add policy rule to share, 'ip' rule represents IPv4 or IPv6 address, 'user' " "rule represents username or usergroup, 'cephx' rule represents Ceph auth ID." msgid "" "Add policy rule to snapshot, 'ip' rule represents ip address, 'user' rule " "represents username or usergroup, 'cephx' rule represents ceph auth ID, and " "'cert' rule represents certificate." msgstr "" "Add policy rule to snapshot, 'ip' rule represents ip address, 'user' rule " "represents username or usergroup, 'cephx' rule represents Ceph auth ID, and " "'cert' rule represents certificate." msgid "Add rule" msgstr "Add rule" msgid "Add security services to share network." msgstr "Add security services to share network." msgid "All keys and values must be in range from 1 to 255." msgstr "All keys and values must be in range from 1 to 255." msgid "All pairs that are in field for left are set for this metadata." msgstr "All pairs that are in field for left are set for this metadata." msgid "All pairs that are in field for left are set for this share group type." msgstr "" "All pairs that are in field for left are set for this share group type." msgid "All pairs that are in field for left are set for this share type." msgstr "All pairs that are in field for left are set for this share type." msgid "Allow project access to share group type." msgstr "Allow project access to share group type." msgid "Allow project access to share type." msgstr "Allow project access to share type." msgid "At least one security service must be specified." msgstr "At least one security service must be specified." msgid "At least one share type must be specified." msgstr "At least one share type must be specified." msgid "Availability Zone" msgstr "Availability Zone" msgid "Availability zone" msgstr "Availability zone" msgctxt "Current status of replica" msgid "Available" msgstr "Available" msgctxt "Current status of share" msgid "Available" msgstr "Available" msgctxt "Current status of snapshot" msgid "Available" msgstr "Available" msgid "Available networks" msgstr "Available networks" msgid "Available projects" msgstr "Available projects" msgid "Available security services" msgstr "Available security services" msgid "Cancel" msgstr "Cancel" msgid "Cancel Migration" msgstr "Cancel Migration" msgid "Cancel migration" msgstr "Cancel migration" msgid "Cancel migration of a Share" msgstr "Cancel migration of a Share" msgid "" "Cancel migration of a migrating share.

This is equivalent to the " "'manila migration-cancel' command." msgstr "" "Cancel migration of a migrating share.

This is equivalent to the " "'manila migration-cancel' command." msgid "Capabilities" msgstr "Capabilities" msgid "Choose a snapshot" msgstr "Choose a snapshot" msgid "Complete Migration" msgstr "Complete Migration" msgid "Complete migration" msgstr "Complete migration" msgid "Complete migration of a Share" msgstr "Complete migration of a Share" msgid "" "Complete migration of a migrating share to another Manila host. This " "operation is expected to be disruptive.

This is equivalent to the " "'manila migration-complete' command." msgstr "" "Complete migration of a migrating share to another Manila host. This " "operation is expected to be disruptive.

This is equivalent to the " "'manila migration-complete' command." msgid "Confirm Migration Cancelling of Share" msgstr "Confirm Migration Cancelling of Share" msgid "Confirm Migration Completion of Share" msgstr "Confirm Migration Completion of Share" msgid "Confirm Obtaining migration progress of Share" msgstr "Confirm Obtaining migration progress of Share" msgid "Confirm Password" msgstr "Confirm Password" msgid "Confirm Unmanage Share" msgstr "Confirm Unmanage Share" msgid "Create" msgstr "Create" msgid "Create Group Share Type" msgstr "Create Group Share Type" msgid "Create Replica" msgstr "Create Replica" msgid "Create Security Service" msgstr "Create Security Service" msgid "Create Share" msgstr "Create Share" msgid "Create Share Group" msgstr "Create Share Group" msgid "Create Share Group Snapshot" msgstr "Create Share Group Snapshot" msgid "Create Share Group Type" msgstr "Create Share Group Type" msgid "Create Share Network" msgstr "Create Share Network" msgid "Create Share Replica" msgstr "Create Share Replica" msgid "Create Share Snapshot" msgstr "Create Share Snapshot" msgid "Create Share Type" msgstr "Create Share Type" msgid "Create a Share" msgstr "Create a Share" msgid "Create share replica in specific availability zone." msgstr "Create share replica in specific availability zone." msgid "Created" msgstr "Created" msgid "Created At" msgstr "Created At" msgid "Created At:" msgstr "Created At:" msgid "Created at" msgstr "Created at" msgctxt "Current status of replica" msgid "Creating" msgstr "Creating" msgctxt "Current status of share" msgid "Creating" msgstr "Creating" msgctxt "Current status of share server" msgid "Creating" msgstr "Creating" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Creating" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Creating replica for share \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Creating rule for \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Creating share \"%s\"" #, python-format msgid "Creating share group \"%s\"" msgstr "Creating share group \"%s\"" #, python-format msgid "Creating share group snapshot \"%s\"." msgstr "Creating share group snapshot \"%s\"." #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Creating share snapshot \"%s\"." #, python-format msgid "Creating snapshot rule for \"%s\"" msgstr "Creating snapshot rule for \"%s\"" msgid "Current Size (GiB)" msgstr "Current Size (GiB)" msgid "DNS IP" msgstr "DNS IP" msgid "Delete Replica" msgid_plural "Delete Replicas" msgstr[0] "Delete Replica" msgstr[1] "Delete Replicas" msgid "Delete Rule" msgid_plural "Delete Rules" msgstr[0] "Delete Rule" msgstr[1] "Delete Rules" msgid "Delete Security Service" msgid_plural "Delete Security Services" msgstr[0] "Delete Security Service" msgstr[1] "Delete Security Services" msgid "Delete Share" msgid_plural "Delete Shares" msgstr[0] "Delete Share" msgstr[1] "Delete Shares" msgid "Delete Share Group" msgid_plural "Delete Share Groups" msgstr[0] "Delete Share Group" msgstr[1] "Delete Share Groups" msgid "Delete Share Group Snapshot" msgid_plural "Delete Share Group Snapshots" msgstr[0] "Delete Share Group Snapshot" msgstr[1] "Delete Share Group Snapshots" msgid "Delete Share Group Type" msgid_plural "Delete Share Group Types" msgstr[0] "Delete Share Group Type" msgstr[1] "Delete Share Group Types" msgid "Delete Share Network" msgid_plural "Delete Share Networks" msgstr[0] "Delete Share Network" msgstr[1] "Delete Share Networks" msgid "Delete Share Server" msgid_plural "Delete Share Server" msgstr[0] "Delete Share Server" msgstr[1] "Delete Share Server" msgid "Delete Share Snapshot" msgid_plural "Delete Share Snapshots" msgstr[0] "Delete Share Snapshot" msgstr[1] "Delete Share Snapshots" msgid "Delete Share Snapshot Rule" msgid_plural "Delete Share Snapshot Rules" msgstr[0] "Delete Share Snapshot Rule" msgstr[1] "Delete Share Snapshot Rules" msgid "Delete Share Type" msgid_plural "Delete Share Types" msgstr[0] "Delete Share Type" msgstr[1] "Delete Share Types" msgid "Delete Snapshot" msgid_plural "Delete Snapshots" msgstr[0] "Delete Snapshot" msgstr[1] "Delete Snapshots" msgid "Delete User Message" msgid_plural "Delete User Messages" msgstr[0] "Delete User Message" msgstr[1] "Delete User Messages" msgid "Deleted Replica" msgid_plural "Deleted Replicas" msgstr[0] "Deleted Replica" msgstr[1] "Deleted Replicas" msgid "Deleted Rule" msgid_plural "Deleted Rules" msgstr[0] "Deleted Rule" msgstr[1] "Deleted Rules" msgid "Deleted Security Service" msgid_plural "Deleted Security Services" msgstr[0] "Deleted Security Service" msgstr[1] "Deleted Security Services" msgid "Deleted Share" msgid_plural "Deleted Shares" msgstr[0] "Deleted Share" msgstr[1] "Deleted Shares" msgid "Deleted Share Group" msgid_plural "Deleted Share Groups" msgstr[0] "Deleted Share Group" msgstr[1] "Deleted Share Groups" msgid "Deleted Share Group Snapshot" msgid_plural "Deleted Share Group Snapshots" msgstr[0] "Deleted Share Group Snapshot" msgstr[1] "Deleted Share Group Snapshots" msgid "Deleted Share Group Type" msgid_plural "Deleted Share Group Types" msgstr[0] "Deleted Share Group Type" msgstr[1] "Deleted Share Group Types" msgid "Deleted Share Network" msgid_plural "Deleted Share Networks" msgstr[0] "Deleted Share Network" msgstr[1] "Deleted Share Networks" msgid "Deleted Share Server" msgid_plural "Deleted Share Server" msgstr[0] "Deleted Share Server" msgstr[1] "Deleted Share Server" msgid "Deleted Share Snapshot" msgid_plural "Deleted Share Snapshots" msgstr[0] "Deleted Share Snapshot" msgstr[1] "Deleted Share Snapshots" msgid "Deleted Share Snapshot Rule" msgid_plural "Deleted Share Snapshot Rules" msgstr[0] "Deleted Share Snapshot Rule" msgstr[1] "Deleted Share Snapshot Rules" msgid "Deleted Share Type" msgid_plural "Deleted Share Types" msgstr[0] "Deleted Share Type" msgstr[1] "Deleted Share Types" msgid "Deleted Snapshot" msgid_plural "Deleted Snapshots" msgstr[0] "Deleted Snapshot" msgstr[1] "Deleted Snapshots" msgid "Deleted User Message" msgid_plural "Deleted User Messages" msgstr[0] "Deleted User Message" msgstr[1] "Deleted User Messages" msgctxt "Current status of replica" msgid "Deleting" msgstr "Deleting" msgctxt "Current status of share" msgid "Deleting" msgstr "Deleting" msgid "Description" msgstr "Description" msgid "Description:" msgstr "Description:" msgid "Destination host and pool where share will be migrated to." msgstr "Destination host and pool where share will be migrated to." msgid "Domain" msgstr "Domain" msgid "Driver handles share servers" msgstr "Driver handles share servers" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Driver options ('volume_id' for Generic driver, etc...)" #, python-format msgid "Duplicated keys '%s'." msgstr "Duplicated keys '%s'." msgid "Edit" msgstr "Edit" msgid "Edit Rule Metadata" msgstr "Edit Rule Metadata" msgid "Edit Security Service" msgstr "Edit Security Service" msgid "Edit Share" msgstr "Edit Share" msgid "Edit Share Metadata" msgstr "Edit Share Metadata" msgid "Edit Share Network" msgstr "Edit Share Network" msgid "Edit Share Snapshot" msgstr "Edit Share Snapshot" msgid "Edit Share network" msgstr "Edit Share network" msgid "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgstr "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgid "" "Enforces migration to be nondisruptive. If set to True, host-assisted " "migration will not be attempted." msgstr "" "Enforces migration to be non-disruptive. If set to True, host-assisted " "migration will not be attempted." msgid "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgstr "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgid "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgstr "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgid "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimizations." msgstr "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimisations." msgctxt "Current status of replica" msgid "Error" msgstr "Error" msgctxt "Current status of share" msgid "Error" msgstr "Error" msgctxt "Current status of share network" msgid "Error" msgstr "Error" msgctxt "Current status of share server" msgid "Error" msgstr "Error" msgctxt "Current status of snapshot" msgid "Error" msgstr "Error" msgid "Expected only pairs of key=value." msgstr "Expected only pairs of key=value." msgid "Expires at" msgstr "Expires at" msgid "Export location" msgstr "Export location" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgid "Export locations" msgstr "Export locations" msgctxt "Current status of share" msgid "Extending Error" msgstr "Extending Error" msgid "Extra Spec " msgstr "Extra Spec " msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgid "Extra specs" msgstr "Extra specs" msgid "Force Host Assisted Migration" msgstr "Force Host Assisted Migration" msgid "From here you can modify name and description of a security service." msgstr "From here you can modify name and description of a security service." msgid "" "From here you can modify name and description of a share group snapshot." msgstr "" "From here you can modify name and description of a share group snapshot." msgid "From here you can modify name and description of a share network." msgstr "From here you can modify name and description of a share network." msgid "From here you can modify name and description of a snapshot." msgstr "From here you can modify name and description of a snapshot." msgid "" "From here you can modify name, description and visibility of a share group." msgstr "" "From here you can modify name, description and visibility of a share group." msgid "From here you can modify name, description and visibility of a share." msgstr "From here you can modify name, description and visibility of a share." msgid "" "From here you can modify name, description, extra specs and visibility of a " "share type." msgstr "" "From here you can modify the name, description, extra specs and visibility " "of a share type." msgid "From here you can revert the share to its latest snapshot." msgstr "From here you can revert the share to its latest snapshot." msgid "From here you can update share network info. " msgstr "From here you can update share network info. " msgid "From here you can update the default share quotas (max limits)." msgstr "From here you can update the default share quotas (max limits)." msgid "Get Migration Progress" msgstr "Get Migration Progress" msgid "Get migration progress" msgstr "Get migration progress" msgid "GiB" msgstr "GiB" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgid "Group specs" msgstr "Group specs" msgid "Here can be modified extra-specs for share type." msgstr "Here can be modified extra-specs for share type." msgid "Here can be modified group-specs for share group type." msgstr "Here can be modified group-specs for share group type." msgid "Host" msgstr "Host" msgid "Host of share" msgstr "Host of share" msgid "Host to migrate share" msgstr "Host to migrate share" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "Host where share is located, example: some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "ID:" msgstr "ID:" msgid "IP Version" msgstr "IP Version" msgid "Id" msgstr "Id" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgctxt "Current status of share server" msgid "In-use" msgstr "In-use" msgctxt "Current status of snapshot" msgid "In-use" msgstr "In-use" msgctxt "Current status of share network" msgid "Inactive" msgstr "Inactive" msgid "Is admin only:" msgstr "Is admin only:" msgid "Is default" msgstr "Is default" #, python-format msgid "Key '%s' has improper length." msgstr "Key '%s' has improper length." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Key can not contain spaces. See string '%s'." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Keys should not contain spaces. Error in '%s'." msgid "Limit" msgstr "Limit" msgid "Make visible to users from all projects" msgstr "Make visible to users from all projects" msgid "Manage" msgstr "Manage" msgctxt "Current status of share" msgid "Manage Error" msgstr "Managed Error" msgid "Manage Replicas" msgstr "Manage Replicas" msgid "Manage Rules" msgstr "Manage Rules" msgid "Manage Share" msgstr "Manage Share" msgid "Manage Share Group Type Access" msgstr "Manage Share Group Type Access" msgid "Manage Share Snapshot Rules" msgstr "Manage Share Snapshot Rules" msgid "Manage Share Type Access" msgstr "Manage Share Type Access" msgid "Message" msgstr "Message" msgid "Message Level" msgstr "Message Level" msgid "Metadata" msgstr "Metadata" msgid "Migrate Share" msgstr "Migrate Share" msgid "Migrate a Share" msgstr "Migrate a Share" msgid "" "Migrate an existing share to another Manila host. This will move all your " "share data from one host to another.

This is equivalent to the " "'manila migration-start' command." msgstr "" "Migrate an existing share to another Manila host. This will move all your " "share data from one host to another.

This is equivalent to the " "'manila migration-start' command." msgctxt "Current status of share" msgid "Migrating" msgstr "Migrating" msgctxt "Current status of share" msgid "Migrating to" msgstr "Migrating to" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "Migration of share %(name)s is at %(progress)s percent." msgid "Mount snapshot support" msgstr "Mount snapshot support" msgid "Name" msgstr "Name" msgid "Name " msgstr "Name " msgid "Name:" msgstr "Name:" msgid "Net Details" msgstr "Net Details" msgid "Network" msgstr "Network" msgid "Network Details" msgstr "Network Details" msgid "Network Type" msgstr "Network Type" msgid "Network handling enabled:" msgstr "Network handling enabled:" msgid "Networks" msgstr "Networks" msgid "Neutron Net" msgstr "Neutron Net" msgid "Neutron Subnet" msgstr "Neutron Subnet" msgid "New Size (GiB)" msgstr "New Size (GiB)" msgid "New share network to be set in migrated share" msgstr "New share network to be set in migrated share" msgid "New share type to be set in migrating share" msgstr "New share type to be set in migrating share" msgid "New size must be different than the existing size" msgstr "New size must be different than the existing size" msgid "New size should not be less than or equal to zero" msgstr "New size should not be less than or equal to zero" msgid "No projects found." msgstr "No projects found." msgid "No projects selected." msgstr "No projects selected." msgid "No security services found." msgstr "No security services found." msgid "No security services selected." msgstr "No security services selected." msgid "No source, empty share" msgstr "No source, empty share" msgid "No source, empty share group" msgstr "No source, empty share group" msgid "Nondisruptive" msgstr "Non-disruptive" msgid "Number of Share Snapshots" msgstr "Number of Share Snapshots" msgid "Number of Shares" msgstr "Number of Shares" msgid "Obtain Progress" msgstr "Obtain Progress" msgid "Obtain migration progress of a Share" msgstr "Obtain migration progress of a Share" msgid "" "Obtains migration progress of a migrating share.

This is " "equivalent to the 'manila migration-get-progress' command." msgstr "" "Obtains migration progress of a migrating share.

This is " "equivalent to the 'manila migration-get-progress' command." msgid "One line - one action. Empty strings will be ignored." msgstr "One line - one action. Empty strings will be ignored." msgid "Organizational Unit" msgstr "Organisational Unit" msgid "Overview" msgstr "Overview" msgid "Password" msgstr "Password" msgid "Passwords do not match." msgstr "Passwords do not match." msgid "Path:" msgstr "Path:" msgid "Placeholder for description of share group type access managing form." msgstr "Placeholder for description of share group type access managing form." msgid "Placeholder for description of share type access managing form." msgstr "Placeholder for description of share type access managing form." msgid "Preferred:" msgstr "Preferred:" msgid "Preserve Metadata" msgstr "Preserve Metadata" msgid "Preserve Snapshots" msgstr "Preserve Snapshots" msgid "Project" msgstr "Project" msgid "Projects with access to share group type" msgstr "Projects with access to share group type" msgid "Projects with access to share type" msgstr "Projects with access to share type" msgid "Protocol" msgstr "Protocol" msgid "Public" msgstr "Public" msgid "Quota Name" msgstr "Quota Name" msgid "Replica Details" msgstr "Replica Details" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Replica Details: %(replica_display_name)s" msgid "Replica State" msgstr "Replica State" msgid "Replica state" msgstr "Replica state" msgid "Replicas" msgstr "Replicas" msgid "Request ID" msgstr "Request ID" msgid "Reset Replica State" msgstr "Reset Replica State" msgid "Reset Replica Status" msgstr "Reset Replica Status" msgid "Reset Share Group Snapshot Status" msgstr "Reset Share Group Snapshot Status" msgid "Reset Share Group Status" msgstr "Reset Share Group Status" msgid "Reset Status" msgstr "Reset Status" msgid "Reset replica state" msgstr "Reset replica state" msgid "Reset replica status" msgstr "Reset replica status" msgid "Reset share replica's state with ID" msgstr "Reset share replica's state with ID" msgid "Reset share replica's status with ID" msgstr "Reset share replica's status with ID" msgid "Reset state" msgstr "Reset state" msgid "Reset status" msgstr "Reset status" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "Resetting replica ('%(id)s') state from '%(from)s' to '%(to)s'." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "Resetting replica ('%(id)s') status from '%(from)s' to '%(to)s'." #, python-format msgid "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." #, python-format msgid "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgid "Resize" msgstr "Resize" msgid "Resize Share" msgstr "Resize Share" msgid "Resize the size of a share. " msgstr "Resize the size of a share. " #, python-format msgid "Resized share \"%s\"" msgstr "Resized share \"%s\"" msgid "Resource ID" msgstr "Resource ID" msgid "Resource Type" msgstr "Resource Type" msgid "Resync" msgstr "Resync" msgid "Resync Replica" msgstr "Resync Replica" msgid "Resync replica" msgstr "Resync replica" msgid "Resync share replica with ID" msgstr "Resync share replica with ID" #, python-format msgid "Resync'ing replica '%s'" msgstr "Resync'ing replica '%s'" msgid "Revert Share" msgstr "Revert Share" msgid "Revert Share to a Snapshot" msgstr "Revert Share to a Snapshot" msgid "Revert share to a snapshot" msgstr "Revert share to a snapshot" msgctxt "Current status of share" msgid "Reverting Error" msgstr "Reverting Error" msgid "Rules" msgstr "Rules" msgid "Save Changes" msgstr "Save Changes" msgid "Security Service Details" msgstr "Security Service Details" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Security Service Details: %(service_display_name)s" msgid "Security Service Overview" msgstr "Security Service Overview" msgid "Security Services" msgstr "Security Services" msgid "Security services within share network" msgstr "Security services within share network" msgid "Segmentation Id" msgstr "Segmentation Id" msgid "Select parameters of share group you want to create. " msgstr "Select parameters of share group you want to create. " msgid "Select parameters of share you want to create. " msgstr "Select parameters of share you want to create. " msgid "Selected Networks" msgstr "Selected Networks" msgid "Selected Projects" msgstr "Selected Projects" msgid "Selected projects" msgstr "Selected projects" msgid "Selected security services" msgstr "Selected security services" msgid "Server" msgstr "Server" msgid "Set Replica as Active" msgstr "Set Replica as Active" msgid "Set as Active" msgstr "Set as Active" msgid "Set maximum quotas for the project." msgstr "Set maximum quotas for the project." msgid "Set share replica with ID" msgstr "Set share replica with ID" #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Setting replica \"%s\" as active..." msgid "Share" msgstr "Share" #, python-format msgid "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgstr "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgid "Share Details" msgstr "Share Details" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Share Details: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Share Details: %(share_name)s" msgid "Share Group" msgstr "Share Group" msgid "Share Group Details" msgstr "Share Group Details" #, python-format msgid "Share Group Details: %s" msgstr "Share Group Details: %s" msgid "Share Group Name" msgstr "Share Group Name" msgid "Share Group Overview" msgstr "Share Group Overview" msgid "Share Group Snapshot" msgstr "Share Group Snapshot" msgid "Share Group Snapshot Details" msgstr "Share Group Snapshot Details" #, python-format msgid "Share Group Snapshot Details: %(sgs_display_name)s" msgstr "Share Group Snapshot Details: %(sgs_display_name)s" msgid "Share Group Snapshot Overview" msgstr "Share Group Snapshot Overview" msgid "Share Group Snapshots" msgstr "Share Group Snapshots" msgid "Share Group Type" msgstr "Share Group Type" msgid "Share Group Type ID:" msgstr "Share Group Type ID:" msgid "Share Group Type Name:" msgstr "Share Group Type Name:" msgid "Share Group Type Specs:" msgstr "Share Group Type Specs:" msgid "Share Group Types" msgstr "Share Group Types" msgid "Share Groups" msgstr "Share Groups" msgid "Share ID" msgstr "Share ID" msgid "Share Instance Details" msgstr "Share Instance Details" #, python-format msgid "Share Instance Details: %s" msgstr "Share Instance Details: %s" msgid "Share Instance Overview" msgstr "Share Instance Overview" msgid "Share Instances" msgstr "Share Instances" msgid "Share Limits" msgstr "Share Limits" msgid "Share Name" msgstr "Share Name" msgid "Share Network" msgstr "Share Network" msgid "Share Network Details" msgstr "Share Network Details" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Share Network Details: %(network_display_name)s" msgid "Share Network Info" msgstr "Share Network Info" msgid "Share Network Overview" msgstr "Share Network Overview" msgid "Share Networks" msgstr "Share Networks" msgid "Share Overview" msgstr "Share Overview" msgid "Share Protocol" msgstr "Share Protocol" msgid "Share Quotas" msgstr "Share Quotas" msgid "Share Replica ID:" msgstr "Share Replica ID:" msgid "Share Replica Overview" msgstr "Share Replica Overview" msgid "Share Replicas" msgstr "Share Replicas" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Share Replicas: %(share_display_name)s" msgid "Share Rules" msgstr "Share Rules" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Share Rules: %(share_display_name)s" msgid "Share Server" msgstr "Share Server" msgid "Share Server Details" msgstr "Share Server Details" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Share Server Details: %(server_name)s" msgid "Share Server Id" msgstr "Share Server Id" msgid "Share Server Overview" msgstr "Share Server Overview" msgid "Share Servers" msgstr "Share Servers" msgid "Share Snapshot Details" msgstr "Share Snapshot Details" msgid "Share Snapshot Name" msgstr "Share Snapshot Name" msgid "Share Snapshot Overview" msgstr "Share Snapshot Overview" msgid "Share Snapshot Rules" msgstr "Share Snapshot Rules" msgid "Share Snapshot gigabytes" msgstr "Share Snapshot gigabytes" msgid "Share Snapshots" msgstr "Share Snapshots" msgid "Share Snapshots Storage" msgstr "Share Snapshots Storage" msgid "" "Share Snapshots are used for storing share changes and creating shares. " msgstr "" "Share Snapshots are used for storing share changes and creating shares. " msgid "Share Source" msgstr "Share Source" msgid "Share Storage" msgstr "Share Storage" msgid "Share Type" msgstr "Share Type" msgid "Share Type Name:" msgstr "Share Type Name:" msgid "Share Type Visibility:" msgstr "Share Type Visibility:" msgid "Share Types" msgstr "Share Types" msgid "Share Types (multiple available)" msgstr "Share Types (multiple available)" msgid "Share Types (one available)" msgstr "Share Types (one available)" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgid "Share gigabytes" msgstr "Share gigabytes" msgid "Share name to be assigned" msgstr "Share name to be assigned" msgid "Share network" msgstr "Share network" msgid "" "Share networks contain network data, that will be used for creation of " "service VM, where will be hosted shares." msgstr "" "Share networks contain network data, that will be used for creation of " "service VM, where will be hosted shares." #, python-format msgid "Share replica %s has been deleted." msgstr "Share replica %s has been deleted." msgid "Share server" msgstr "Share server" #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "Share size must be equal to or greater than the snapshot size (%sGiB)" msgid "Share snapshot gigabytes" msgstr "Share snapshot gigabytes" msgid "Share snapshots" msgstr "Share snapshots" msgid "Share type" msgstr "Share type" msgid "Share types" msgstr "Share types" msgid "Shared Quotas" msgstr "Shared Quotas" msgid "Shares" msgstr "Shares" msgid "Shares on this server" msgstr "Shares on this server" msgctxt "Current status of share" msgid "Shrinking Error" msgstr "Shrinking Error" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Size" msgid "Size (GiB)" msgstr "Size (GiB)" msgid "Snapshot" msgstr "Snapshot" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Snapshot Details: %(snapshot_display_name)s" msgid "Snapshot ID" msgstr "Snapshot ID" msgid "Snapshot Overview" msgstr "Snapshot Overview" msgid "Snapshot Replica ID:" msgstr "Snapshot Replica ID:" #, python-format msgid "Snapshot Rules: %(snapshot_display_name)s" msgstr "Snapshot Rules: %(snapshot_display_name)s" msgid "Source" msgstr "Source" msgid "Source SG Snapshot" msgstr "Source SG Snapshot" msgid "Source Share Group" msgstr "Source Share Group" msgid "Source Share Group Snapshot" msgstr "Source Share Group Snapshot" msgid "Source Type" msgstr "Source Type" msgid "Source share group snapshot" msgstr "Source share group snapshot" msgid "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgstr "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgid "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgstr "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgid "Specs" msgstr "Specs" msgid "Start migration" msgstr "Start migration" msgid "Status" msgstr "Status" msgid "Status:" msgstr "Status:" msgid "Submit" msgstr "Submit" msgid "Subnet" msgstr "Subnet" #, python-format msgid "Successfully created security service: %s" msgstr "Successfully created security service: %s" #, python-format msgid "Successfully created share group type: %s" msgstr "Successfully created share group type: %s" #, python-format msgid "Successfully created share network: %s" msgstr "Successfully created share network: %s" #, python-format msgid "Successfully created share type: %s" msgstr "Successfully created share type: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "Successfully sent the request to cancel migration of share: %s." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "Successfully sent the request to complete migration of share: %s." #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Successfully sent the request to manage share: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "Successfully sent the request to migrate share: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "Successfully sent the request to unmanage share: %s" #, python-format msgid "Successfully updated group specs for share group type '%s'." msgstr "Successfully updated group specs for share group type '%s'." #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Successfully updated security service \"%s\"" #, python-format msgid "Successfully updated share type '%s'." msgstr "Successfully updated share type '%s'." msgid "Task state" msgstr "Task state" msgid "The operation timed out while resizing. Please try again." msgstr "The operation timed out while resizing. Please try again." msgid "" "The security service can be used by backend drivers to configure clients, " "for more secure using of share." msgstr "" "The security service can be used by backend drivers to configure clients, " "for more secure using of share." msgid "" "The share group type defines the characteristics of a share group backend." msgstr "" "The share group type defines the characteristics of a share group backend." #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "The share size cannot be less than the snapshot size (%sGiB)" msgid "The share type defines the characteristics of a share backend." msgstr "The share type defines the characteristics of a share backend." msgid "To add extra-specs use:" msgstr "To add extra-specs use:" msgid "To add group-specs use:" msgstr "To add group-specs use:" msgid "To add metadata use:" msgstr "To add metadata use:" msgid "To unset extra-specs use:" msgstr "To unset extra-specs use:" msgid "To unset group-specs use:" msgstr "To unset group-specs use:" msgid "To unset metadata use:" msgstr "To unset metadata use:" msgid "Total Gibibytes" msgstr "Total Gibibytes" msgid "Type" msgstr "Type" msgid "Unable to add rule." msgstr "Unable to add rule." msgid "Unable to add snapshot rule." msgstr "Unable to add snapshot rule." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "Unable to cancel migration of share %s at this moment." #, python-format msgid "Unable to complete migration of share %s." msgstr "Unable to complete migration of share %s." msgid "Unable to create security service." msgstr "Unable to create security service." msgid "Unable to create share group snapshot." msgstr "Unable to create share group snapshot." msgid "Unable to create share group type." msgstr "Unable to create share group type." msgid "Unable to create share group." msgstr "Unable to create share group." msgid "Unable to create share network." msgstr "Unable to create share network." msgid "Unable to create share replica." msgstr "Unable to create share replica." msgid "Unable to create share snapshot." msgstr "Unable to create share snapshot." msgid "Unable to create share type." msgstr "Unable to create share type." msgid "Unable to create share." msgstr "Unable to create share." #, python-format msgid "Unable to create share. %s" msgstr "Unable to create share. %s" #, python-format msgid "Unable to delete message \"%s\"" msgstr "Unable to delete message \"%s\"" #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Unable to delete replica \"%s\"." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Unable to delete rule \"%s\"." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Unable to delete share \"%s\". " #, python-format msgid "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." msgstr "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "Unable to delete snapshot \"%s\". One or more shares depend on it." #, python-format msgid "Unable to delete snapshot rule \"%s\"." msgstr "Unable to delete snapshot rule \"%s\"." msgid "Unable to get information about share group type access." msgstr "Unable to get information about share group type access." msgid "Unable to get information about share type access." msgstr "Unable to get information about share type access." msgid "Unable to get list of projects." msgstr "Unable to get list of projects." msgid "Unable to get manila default quota." msgstr "Unable to get Manila default quota." msgid "Unable to get the security services hosts" msgstr "Unable to get the security services hosts" #, python-format msgid "Unable to get the specified share group '%s' for snapshot creation." msgstr "Unable to get the specified share group '%s' for snapshot creation." msgid "Unable to load the specified share group snapshot." msgstr "Unable to load the specified share group snapshot." msgid "Unable to load the specified snapshot." msgstr "Unable to load the specified snapshot." msgid "Unable to manage share" msgstr "Unable to manage share" #, python-format msgid "Unable to migrate share %s." msgstr "Unable to migrate share %s." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "Unable to obtain progress of migration of share %s at this moment." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "Unable to reset state of replica '%s'." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "Unable to reset status of replica '%s'." #, python-format msgid "Unable to reset status of share group '%s'." msgstr "Unable to reset status of share group '%s'." #, python-format msgid "Unable to reset status of share group snapshot '%s'." msgstr "Unable to reset status of share group snapshot '%s'." msgid "Unable to resize share." msgstr "Unable to resize share." msgid "Unable to resize share. " msgstr "Unable to resize share. " #, python-format msgid "Unable to resync replica '%s'." msgstr "Unable to resync replica '%s'." msgid "Unable to retrieve default share quotas." msgstr "Unable to retrieve default share quotas." #, python-format msgid "Unable to retrieve details of replica %s" msgstr "Unable to retrieve details of replica %s" msgid "Unable to retrieve list of projects." msgstr "Unable to retrieve list of projects." msgid "Unable to retrieve messages list." msgstr "Unable to retrieve messages list." msgid "Unable to retrieve quotas." msgstr "Unable to retrieve quotas." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Unable to retrieve replica '%s'." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Unable to retrieve security service '%s' details." msgid "Unable to retrieve security services" msgstr "Unable to retrieve security services" msgid "Unable to retrieve security_service." msgstr "Unable to retrieve security_service." msgid "Unable to retrieve share access rule." msgstr "Unable to retrieve share access rule." msgid "Unable to retrieve share details." msgstr "Unable to retrieve share details." #, python-format msgid "Unable to retrieve share group '%s'." msgstr "Unable to retrieve share group '%s'." msgid "Unable to retrieve share group details." msgstr "Unable to retrieve share group details." #, python-format msgid "Unable to retrieve share group snapshot '%s'." msgstr "Unable to retrieve share group snapshot '%s'." msgid "Unable to retrieve share group snapshot details." msgstr "Unable to retrieve share group snapshot details." msgid "Unable to retrieve share group snapshot list." msgstr "Unable to retrieve share group snapshot list." msgid "Unable to retrieve share group snapshot." msgstr "Unable to retrieve share group snapshot." msgid "Unable to retrieve share group snapshots." msgstr "Unable to retrieve share group snapshots." msgid "Unable to retrieve share group types." msgstr "Unable to retrieve share group types." msgid "Unable to retrieve share group." msgstr "Unable to retrieve share group." msgid "Unable to retrieve share groups." msgstr "Unable to retrieve share groups." msgid "Unable to retrieve share instance details." msgstr "Unable to retrieve share instance details." msgid "Unable to retrieve share instances." msgstr "Unable to retrieve share instances." msgid "Unable to retrieve share limit information." msgstr "Unable to retrieve share limit information." msgid "Unable to retrieve share list." msgstr "Unable to retrieve share list." msgid "Unable to retrieve share network details." msgstr "Unable to retrieve share network details." msgid "Unable to retrieve share network." msgstr "Unable to retrieve share network." msgid "Unable to retrieve share networks" msgstr "Unable to retrieve share networks" msgid "Unable to retrieve share quotas." msgstr "Unable to retrieve share quotas." msgid "Unable to retrieve share replicas." msgstr "Unable to retrieve share replicas." msgid "Unable to retrieve share rules." msgstr "Unable to retrieve share rules." msgid "Unable to retrieve share server details." msgstr "Unable to retrieve share server details." msgid "Unable to retrieve share servers" msgstr "Unable to retrieve share servers" msgid "Unable to retrieve share snapshot list." msgstr "Unable to retrieve share snapshot list." msgid "Unable to retrieve share snapshot rules." msgstr "Unable to retrieve share snapshot rules." msgid "Unable to retrieve share snapshot." msgstr "Unable to retrieve share snapshot." msgid "Unable to retrieve share snapshots list." msgstr "Unable to retrieve share snapshots list." msgid "Unable to retrieve share snapshots." msgstr "Unable to retrieve share snapshots." msgid "Unable to retrieve share types." msgstr "Unable to retrieve share types." msgid "Unable to retrieve share." msgstr "Unable to retrieve share." #, python-format msgid "Unable to retrieve share. %s" msgstr "Unable to retrieve share. %s" msgid "Unable to retrieve share_gruop_type." msgstr "Unable to retrieve share_group_type." msgid "Unable to retrieve share_type." msgstr "Unable to retrieve share_type." msgid "Unable to retrieve snapshot details." msgstr "Unable to retrieve snapshot details." msgid "Unable to retrieve snapshot." msgstr "Unable to retrieve snapshot." msgid "Unable to retrieve user message detail." msgstr "Unable to retrieve user message detail." msgid "Unable to retrieve volume details." msgstr "Unable to retrieve volume details." msgid "Unable to revert share to the snapshot." msgstr "Unable to revert share to the snapshot." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Unable to set replica '%s' as active." msgid "Unable to unmanage share." msgstr "Unable to unmanage share." #, python-format msgid "Unable to update access for share group type \"%s\"." msgstr "Unable to update access for share group type \"%s\"." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Unable to update access for share type \"%s\"." msgid "Unable to update default quotas." msgstr "Unable to update default quotas." msgid "Unable to update group_specs for share group type." msgstr "Unable to update group_specs for share group type." msgid "Unable to update rule metadata." msgstr "Unable to update rule metadata." msgid "Unable to update security service." msgstr "Unable to update security service." msgid "Unable to update share group snapshot." msgstr "Unable to update share group snapshot." msgid "Unable to update share group type." msgstr "Unable to update share group type." msgid "Unable to update share group." msgstr "Unable to update share group." msgid "Unable to update share metadata." msgstr "Unable to update share metadata." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Unable to update share network \"%s\"." msgid "Unable to update share network." msgstr "Unable to update share network." msgid "Unable to update share snapshot." msgstr "Unable to update share snapshot." msgid "Unable to update share type." msgstr "Unable to update share type." msgid "Unable to update share." msgstr "Unable to update share." msgid "Unknown" msgstr "Unknown" msgid "Unmanage" msgstr "Unmanage" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Unmanaged Error" msgid "Unmanage Share" msgstr "Unmanage Share" msgid "Update" msgstr "Update" msgid "Update Share Group" msgstr "Update Share Group" msgid "Update Share Group Snapshot" msgstr "Update Share Group Snapshot" msgid "Update Share Group Type" msgstr "Update Share Group Type" msgid "Update Share Network" msgstr "Update Share Network" msgid "Update Share Snapshot" msgstr "Update Share Snapshot" msgid "Update Share Type" msgstr "Update Share Type" msgid "Update Share group Type" msgstr "Update Share group Type" msgid "Update share network" msgstr "Update share network" msgid "Updated" msgstr "Updated" msgid "Updated At" msgstr "Updated At" msgid "Updated At:" msgstr "Updated At:" #, python-format msgid "Updated access for share group type \"%s\"." msgstr "Updated access for share group type \"%s\"." #, python-format msgid "Updated access for share type \"%s\"." msgstr "Updated access for share type \"%s\"." #, python-format msgid "Updated share network \"%s\"." msgstr "Updated share network \"%s\"." #, python-format msgid "Updating share \"%s\"" msgstr "Updating share \"%s\"" msgid "Updating share access rule metadata " msgstr "Updating share access rule metadata " #, python-format msgid "Updating share group \"%s\"" msgstr "Updating share group \"%s\"" #, python-format msgid "Updating share group snapshot \"%s\"" msgstr "Updating share group snapshot \"%s\"" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Updating share metadata \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Updating share network \"%s\"" #, python-format msgid "Updating share snapshot \"%s\"" msgstr "Updating share snapshot \"%s\"" msgid "Use share group snapshot as a source" msgstr "Use share group snapshot as a source" msgid "Use snapshot as a source" msgstr "Use snapshot as a source" msgid "User" msgstr "User" msgid "User Message" msgstr "User Message" #, python-format msgid "User Message Details: %(message_id)s" msgstr "User Message Details: %(message_id)s" msgid "User Messages" msgstr "User Messages" msgid "User Messages Detail" msgstr "User Messages Detail" msgid "User Messages Details" msgstr "User Messages Details" msgid "User Messages Overview" msgstr "User Messages Overview" msgid "Visibility" msgstr "Visibility" msgid "" "When a share is \"unmanaged\", the share will no longer be visible within " "OpenStack. Note that the share will not be deleted.

This is " "equivalent to the 'manila unmanage' command." msgstr "" "When a share is \"unmanaged\", the share will no longer be visible within " "OpenStack. Note that the share will not be deleted.

This is " "equivalent to the 'manila unmanage' command." msgid "Writable" msgstr "Writable" msgid "as Active?" msgstr "as Active?" msgid "key=value pairs per line can be set" msgstr "key=value pairs per line can be set" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/fr/0000775000175000017500000000000000000000000017274 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/fr/LC_MESSAGES/0000775000175000017500000000000000000000000021061 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/fr/LC_MESSAGES/django.po0000664000175000017500000005722200000000000022673 0ustar00zuulzuul00000000000000# Gérald LONLAS , 2016. #zanata # Benjamin ACH , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-02-25 11:57+0000\n" "Last-Translator: Benjamin ACH \n" "Language-Team: French\n" "Language: fr\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" #, python-format msgid "%sGiB" msgstr "%sGio" msgid "(Quota exceeded)" msgstr "(Quota dépassé)" msgid "Access Key" msgstr "Clef d’accès" msgid "Access Level" msgstr "Niveau d'accès" msgid "Access To" msgstr "Accès à" msgid "Access Type" msgstr "Type d'accès" msgid "Access to" msgstr "Accès à" msgctxt "Current status of share network" msgid "Active" msgstr "Actif" msgctxt "Current status of share server" msgid "Active" msgstr "Actif" msgid "Add" msgstr "Ajouter" msgid "Add Rule" msgstr "Ajouter une règle" msgid "Add Security Service" msgstr "Ajout d'un service de sécurité " msgid "Add rule" msgstr "Ajouter une règle" msgid "Add security services to share network." msgstr "Ajout du service de sécurité au partage réseau." msgid "All keys and values must be in range from 1 to 255." msgstr "Toutes les clés doit avoir une valeur comprise dans la plage 1 à 255." msgid "Allow project access to share type." msgstr "Autoriser un projet à accéder au type de partage." msgid "At least one security service must be specified." msgstr "Au moins un service de sécurité doit être indiqué." msgid "Availability Zone" msgstr "Zone de disponibilité" msgid "Availability zone" msgstr "Zone de disponibilité" msgctxt "Current status of replica" msgid "Available" msgstr "Disponible" msgctxt "Current status of share" msgid "Available" msgstr "Disponible" msgctxt "Current status of snapshot" msgid "Available" msgstr "Disponible" msgid "Available projects" msgstr "Projets disponibles" msgid "Available security services" msgstr "Service de sécurité disponible." msgid "Cancel Migration" msgstr "Annuler la migration" msgid "Cancel migration" msgstr "Annuler la migration" msgid "Cancel migration of a Share" msgstr "Annuler la migration d'un partage" msgid "Choose a snapshot" msgstr "Choisir un instantané" msgid "Complete Migration" msgstr "Migration terminée" msgid "Complete migration" msgstr "Migration terminée" msgid "Complete migration of a Share" msgstr "Migration du partage avec succès" msgid "Confirm Migration Cancelling of Share" msgstr "Confirmer l'annulation de la migration du partage" msgid "Confirm Migration Completion of Share" msgstr "Confirmer l'avancement de la migration du partage" msgid "Confirm Password" msgstr "Confirmer le mot de passe" msgid "Confirm Unmanage Share" msgstr "Confirmer le partage non-géré" msgid "Create" msgstr "Créer" msgid "Create Replica" msgstr "Créer un replica" msgid "Create Security Service" msgstr "Créer un service de sécurité " msgid "Create Share" msgstr "Créer un partage" msgid "Create Share Network" msgstr "Créer un partage réseau" msgid "Create Share Snapshot" msgstr "Créer l'instantané du partage" msgid "Create Share Type" msgstr "Créer un type de partage" msgid "Create a Share" msgstr "Créer un partage" msgid "Created At" msgstr "Créé le" msgctxt "Current status of replica" msgid "Creating" msgstr "Création en cours" msgctxt "Current status of share" msgid "Creating" msgstr "Création en cours" msgctxt "Current status of share server" msgid "Creating" msgstr "Création en cours" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Création en cours" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Création du réplica pour le partage \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Création de la règle pour \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Création du partage \"%s\"" #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Création de l'instantané partagé \"%s\"." msgid "Current Size (GiB)" msgstr "Taille actuelle (Gio)" msgid "DNS IP" msgstr "IP DNS" msgctxt "Current status of replica" msgid "Deleting" msgstr "Suppression en cours" msgctxt "Current status of share" msgid "Deleting" msgstr "Suppression en cours" msgid "Description" msgstr "Description" msgid "Destination host and pool where share will be migrated to." msgstr "Hôte de destination et pool où le partage sera migré." msgid "Domain" msgstr "Domaine" msgid "Driver handles share servers" msgstr "Pilote qui supporte les partages serveur" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Option du pilote ('volume_id' pour les Generic driver, etc...)" #, python-format msgid "Duplicated keys '%s'." msgstr "Clés dupliquées '%s'." msgid "Edit" msgstr "Éditer" msgid "Edit Security Service" msgstr "Éditer le service de sécurité " msgid "Edit Share" msgstr "Éditer le partage" msgid "Edit Share Metadata" msgstr "Éditer les métadonnées du partage" msgid "Edit Share Network" msgstr "Éditer le partage réseau" msgctxt "Current status of replica" msgid "Error" msgstr "Erreur" msgctxt "Current status of share" msgid "Error" msgstr "Erreur" msgctxt "Current status of share network" msgid "Error" msgstr "Erreur" msgctxt "Current status of share server" msgid "Error" msgstr "Erreur" msgctxt "Current status of snapshot" msgid "Error" msgstr "Erreur" msgid "Expected only pairs of key=value." msgstr "Seule les paires de clé-valeur key=value sont attendus." msgid "Export location" msgstr "Emplacement de l'export" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "" "Emplacement de l'export du partage. Par exemple pour NFS : 1.2.3.4:/path/to/" "share" msgctxt "Current status of share" msgid "Extending Error" msgstr "Erreur étendue" msgid "Extra specs" msgstr "Spécifications supplémentaires" msgid "Force Host Assisted Migration" msgstr "Forcer la migration assisté de l'hôte" msgid "From here you can update share network info. " msgstr "D'ici, vous pouvez mettre à jour les informations du partage réseau." msgid "Get migration progress" msgstr "Voir l'avancement de la migration" msgid "Host" msgstr "Hôte" msgid "Host of share" msgstr "Hôte du partage" msgid "Host to migrate share" msgstr "Hôte pour la migration du partage" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "Hôte où se trouve le partage, exemple : some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "Version d'IP" msgid "Id" msgstr "ID" msgctxt "Current status of share server" msgid "In-use" msgstr "En cours d'utilisation" msgctxt "Current status of snapshot" msgid "In-use" msgstr "En cours d'utilisation" msgctxt "Current status of share network" msgid "Inactive" msgstr "Inactif" #, python-format msgid "Key '%s' has improper length." msgstr "La clé '%s' a une longueur inappropriée." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "La clé ne peut pas contenir d'espace. Voir la chaine '%s'." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "La clé ne peut pas contenir d'espace. Erreur dans '%s'." msgid "Manage" msgstr "Gérer" msgctxt "Current status of share" msgid "Manage Error" msgstr "Erreur gérée" msgid "Manage Replicas" msgstr "Gérer les réplicas" msgid "Manage Rules" msgstr "Gérer les règles" msgid "Manage Share" msgstr "Gérer le partage" msgid "Manage Share Type Access" msgstr "Gérer les accès du type de partage" msgid "Metadata" msgstr "Métadonnées" msgid "Migrate Share" msgstr "Migrer le partage" msgid "Migrate a Share" msgstr "Migrer le partage" msgctxt "Current status of share" msgid "Migrating" msgstr "Migration en cours" msgctxt "Current status of share" msgid "Migrating to" msgstr "Migration vers" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "Migration du partage %(name)s est à %(progress)s pourcent(s)." msgid "Name" msgstr "Nom" msgid "Network Type" msgstr "Type de réseau" msgid "Networks" msgstr "Réseaux" msgid "Neutron Net" msgstr "Neutron Net" msgid "Neutron Subnet" msgstr "Sous-réseau Neutron" msgid "New Size (GiB)" msgstr "Nouvelle taille (Gio)" msgid "New share network to be set in migrated share" msgstr "Le nouveau partage réseau doit être mis dans le partage migré" msgid "New share type to be set in migrating share" msgstr "" "Nouveau type de partage qui doit être appliqué dans la migration de partage" msgid "No projects found." msgstr "Aucun projet trouvé." msgid "No projects selected." msgstr "Aucun projet sélectionné." msgid "No security services found." msgstr "Aucun service de sécurité trouvé." msgid "No security services selected." msgstr "Aucun service de sécurité sélectionné." msgid "No source, empty share" msgstr "Aucune source, partage vide" msgid "Nondisruptive" msgstr "Non perturbateur " msgid "Obtain Progress" msgstr "" "\t\n" "Voir l'avancement" msgid "Obtain migration progress of a Share" msgstr "Voir l'avancement de la migration d'un partage" msgid "Overview" msgstr "Vue d'ensemble" msgid "Password" msgstr "Mot de passe" msgid "Passwords do not match." msgstr "Les mots de passe ne correspondent pas." msgid "Preserve Metadata" msgstr "Préserver les métadonnées" msgid "Preserve Snapshots" msgstr "Conserver les instantanés" msgid "Project" msgstr "Projet" msgid "Projects with access to share type" msgstr "Projets avec un accès au type de partage" msgid "Protocol" msgstr "Protocole" msgid "Public" msgstr "Public" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Détail du replica : %(replica_display_name)s" msgid "Replica State" msgstr "État du replica" msgid "Replicas" msgstr "Réplicas" msgid "Reset Replica State" msgstr "Réinitialiser l'état du replica" msgid "Reset Replica Status" msgstr "Réinitialiser le statut du replica" msgid "Reset replica state" msgstr "Réinitialiser l'état du replica" msgid "Reset replica status" msgstr "Réinitialiser le statut du replica" msgid "Reset state" msgstr "Réinitialiser l'état" msgid "Reset status" msgstr "Réinitialiser le statut" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "" "Réinitialisation de l'état du replica ('%(id)s') de '%(from)s' à '%(to)s'." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Réinitialisation du statut du replica ('%(id)s') de '%(from)s' à '%(to)s'." msgid "Resync" msgstr "Resynchroniser" msgid "Resync Replica" msgstr "Resynchroniser le replica" msgid "Resync replica" msgstr "Resynchroniser le replica" #, python-format msgid "Resync'ing replica '%s'" msgstr "Resynchronisation du replica \"%s\"" msgid "Rules" msgstr "Règles" msgid "Save Changes" msgstr "Sauvegarder les modifications" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Détail du service de sécurité : %(service_display_name)s" msgid "Security Services" msgstr "Services de sécurité" msgid "Security services within share network" msgstr "Service de sécurité dans le partage réseau" msgid "Segmentation Id" msgstr "ID segmentation" msgid "Selected projects" msgstr "Projets sélectionnés" msgid "Selected security services" msgstr "Service de sécurité sélectionné" msgid "Server" msgstr "Serveur" msgid "Set Replica as Active" msgstr "Mettre le replica \"%s\" à actif" msgid "Set as Active" msgstr "Mettre à actif" msgid "Set maximum quotas for the project." msgstr "Définir les quotas maximum pour le projet." #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Mettre le replica \"%s\" à actif" msgid "Share" msgstr "Partage" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Détails du partage : %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Détails du partage : %(share_name)s" msgid "Share ID" msgstr "ID du partage" #, python-format msgid "Share Instance Details: %s" msgstr "Détails du partage d'instance : %s" msgid "Share Instances" msgstr "Partage d'instance" msgid "Share Name" msgstr "Nom du partage" msgid "Share Network" msgstr "Partage réseau" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Détail du partage réseau : %(network_display_name)s" msgid "Share Network Info" msgstr "Informations du partage réseau" msgid "Share Networks" msgstr "Partages réseau" msgid "Share Protocol" msgstr "Protocole de partage" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Replicas du partage : %(share_display_name)s" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Règles du partage : %(share_display_name)s" msgid "Share Server" msgstr "Partage serveur" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Détails du partage serveur : %(server_name)s" msgid "Share Server Id" msgstr "ID du partage serveur" msgid "Share Servers" msgstr "Partages serveur" msgid "Share Snapshots" msgstr "Instantanés de partage" msgid "Share Snapshots Storage" msgstr "Instantané du partage de stockage" msgid "Share Source" msgstr "Source du partage" msgid "Share Storage" msgstr "Partage de stockage" msgid "Share Type" msgstr "Type de partage" msgid "Share Types" msgstr "Types de partage" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Le partage ne peut pas être étendu à %(req)iGio car vous avez disposez " "uniquement d'un quota de %(avail)iGio." msgid "Share name to be assigned" msgstr "Nom du partage à donner" #, python-format msgid "Share replica %s has been deleted." msgstr "Le partage de replica %s a été supprimé." #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "" "La taille du partage doit être supérieure ou égale à la taille de " "l'instantané (%sGio)" msgid "Shares" msgstr "Partages" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Taille" msgid "Size (GiB)" msgstr "Taille (Gio)" msgid "Snapshot" msgstr "Instantané" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Détails de l'instantané : %(snapshot_display_name)s" msgid "Snapshot Overview" msgstr "Aperçu de l'instantané" msgid "Source" msgstr "Source" msgid "Start migration" msgstr "Démarrer la migration" msgid "Status" msgstr "Statut" #, python-format msgid "Successfully created security service: %s" msgstr "Service de sécurité créé avec succès : %s" #, python-format msgid "Successfully created share network: %s" msgstr "Partage réseau créé avec succès : %s" #, python-format msgid "Successfully created share type: %s" msgstr "Le type de partage a été créé : %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "" "La demande pour annuler la migration du partage a été envoyée avec succès : " "%s" #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "" "La demande pour finir la migration du partage a été envoyée avec succès : %s" #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "La demande de gestion du partage a été envoyée avec succès : %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "La demande de migration du partage a été envoyée avec succès : %s" #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "La demande de non-gestion du partage a été envoyée avec succès : %s" #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Service de sécurité \"%s\" mis à jour avec succès" #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "" "La taille du partage ne peut pas être inférieure à la taille de l'instantané " "(%sGio)" msgid "Type" msgstr "Type" msgid "Unable to add rule." msgstr "Impossible d'ajouter la règle." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "Il est impossible pour le moment d'annuler la migration du partage %s." #, python-format msgid "Unable to complete migration of share %s." msgstr "Impossible de finir la migration du partage %s." msgid "Unable to create security service." msgstr "Impossible de créer le service de sécurité." msgid "Unable to create share network." msgstr "Impossible de créer le partage réseau." msgid "Unable to create share replica." msgstr "Impossible de créer le partage de replica." msgid "Unable to create share snapshot." msgstr "Impossible de créer un instantané partagé." msgid "Unable to create share type." msgstr "Impossible de créer le type de partage." msgid "Unable to create share." msgstr "Impossible de créer le partage." #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Impossible de supprimer le replica \"%s\"." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Impossible de supprimer la règle \"%s\"." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Impossible de supprimer le partage \"%s\"" #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "Impossible de supprimer l'instantané \"%s\". Un ou plusieurs partages " "dépendent de lui." msgid "Unable to get information about share type access." msgstr "" "Impossible de récupérer les information au sujet des accès sur le type de " "partage." msgid "Unable to get list of projects." msgstr "Impossible d'obtenir la liste des projets" msgid "Unable to get the security services hosts" msgstr "Impossible de récupérer les hôtes des services de sécurité" msgid "Unable to load the specified snapshot." msgstr "Impossible de charger l'instantané spécifié." msgid "Unable to manage share" msgstr "Impossible de gérer le partage." #, python-format msgid "Unable to migrate share %s." msgstr "Impossible de migrer le partage %s." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "" "Il est impossible pour le moment d'obtenir la progression de la migration du " "partage %s." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "Impossible de réinitialiser l'état du replica \"%s\"." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "Impossible de réinitialiser le statut du replica \"%s\"." #, python-format msgid "Unable to resync replica '%s'." msgstr "Impossible de synchroniser le replica \"%s\"." msgid "Unable to retrieve list of projects." msgstr "Impossible de récupérer la liste des projets." msgid "Unable to retrieve quotas." msgstr "Impossible de récupérer les quotas." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Impossible de récupérer le replica \"%s\"." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Impossible de récupérer les détails du service de sécurité \"%s\"." msgid "Unable to retrieve security services" msgstr "Impossible de récupérer les services de sécurité." msgid "Unable to retrieve security_service." msgstr "Impossible de récupérer security_service." msgid "Unable to retrieve share details." msgstr "Impossible de récupérer les détails du partage." msgid "Unable to retrieve share instance details." msgstr "Impossible de récupérer les détails du partage d'instance." msgid "Unable to retrieve share instances." msgstr "Impossible de récupérer les partages d'instance" msgid "Unable to retrieve share limit information." msgstr "Impossible de récupérer les informations de limite du partage." msgid "Unable to retrieve share list." msgstr "Impossible de récupérer la liste des partages." msgid "Unable to retrieve share network details." msgstr "Impossible de récupérer les détails du partage réseau." msgid "Unable to retrieve share network." msgstr "Impossible de récupérer le partage réseau." msgid "Unable to retrieve share networks" msgstr "Impossible de récupérer les partages réseau" msgid "Unable to retrieve share replicas." msgstr "Impossible de récupérer les partages de replica." msgid "Unable to retrieve share rules." msgstr "Impossible de récupérer la liste des partages." msgid "Unable to retrieve share server details." msgstr "Impossible de récupérer les détails du partage serveur." msgid "Unable to retrieve share servers" msgstr "Impossible de récupérer les partages de serveur" msgid "Unable to retrieve share snapshots list." msgstr "Impossible de récupérer la liste des instantanés partagés." msgid "Unable to retrieve share snapshots." msgstr "Impossible de récupérer les instantanés du partage." msgid "Unable to retrieve share." msgstr "Impossible de récupérer le partage." #, python-format msgid "Unable to retrieve share. %s" msgstr "Impossible de récupérer les partages \"%s\"." msgid "Unable to retrieve share_type." msgstr "Impossible de récupérer le share_type." msgid "Unable to retrieve snapshot details." msgstr "Impossible de récupérer les détails de l'instantané." msgid "Unable to retrieve snapshot." msgstr "Impossible de récupérer l'instantané." msgid "Unable to retrieve volume details." msgstr "Impossible de récupérer les détails du volume." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Impossible de mettre le replica \"%s\" à actif." msgid "Unable to unmanage share." msgstr "Impossible de ne pas gérer le partage." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Impossible de mettre à jour le type de partage \"%s\"." msgid "Unable to update default quotas." msgstr "Impossible de mettre à jour les quotas par défaut." msgid "Unable to update security service." msgstr "Impossible de mettre à jour le service de sécurité." msgid "Unable to update share metadata." msgstr "Impossible de mettre à jour les métadonnées du partage." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Impossible de mettre à jour le partage réseau \"%s\"." msgid "Unable to update share network." msgstr "Impossible de mettre à jour le partage réseau." msgid "Unable to update share type." msgstr "Impossible de mettre à jour le type de partage." msgid "Unable to update share." msgstr "Impossible de mettre à jour le partage." msgid "Unknown" msgstr "Inconnu" msgid "Unmanage" msgstr "Non-géré" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Erreur non-gérée" msgid "Unmanage Share" msgstr "Partage non-géré" msgid "Update" msgstr "Mettre à jour" msgid "Update Share Network" msgstr "Mettre à jour le partage réseau" msgid "Update Share Type" msgstr "Mise à jour du type de partage" msgid "Updated At" msgstr "Mis à jour à" #, python-format msgid "Updated access for share type \"%s\"." msgstr "Mise à jour des accès pour le type de partage : \"%s\"." #, python-format msgid "Updated share network \"%s\"." msgstr "Partage réseau mis à jour \"%s\"." #, python-format msgid "Updating share \"%s\"" msgstr "Mise à jour du partage \"%s\"" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Mise à jour des métadonnées du partage \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Mise à jour en cours du partage réseau \"%s\"" msgid "Use snapshot as a source" msgstr "Utiliser un instantané comme source" msgid "User" msgstr "Utilisateur" msgid "Visibility" msgstr "Visibilité" msgid "Writable" msgstr "Accessible en écriture" msgid "key=value pairs per line can be set" msgstr "paires de clé-valeur key=value par ligne peut être mise" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/id/0000775000175000017500000000000000000000000017261 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/id/LC_MESSAGES/0000775000175000017500000000000000000000000021046 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/id/LC_MESSAGES/django.po0000664000175000017500000014071000000000000022653 0ustar00zuulzuul00000000000000# suhartono , 2016. #zanata # Andreas Jaeger , 2017. #zanata # suhartono , 2017. #zanata # suhartono , 2018. #zanata # suhartono , 2019. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2019-03-12 06:13+0000\n" "Last-Translator: suhartono \n" "Language-Team: Indonesian\n" "Language: id\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "" "\"Manage\" an existing share from a Manila host. This will make the share " "visible within OpenStack.

This is equivalent to the 'manila " "manage' command." msgstr "" "\"Manage\" bagian yang ada dari Manila host. Ini akan membuat share terlihat " "dalam OpenStack.

Ini sama dengan perintah 'manila manage' ." #, python-format msgid "%(used)s of %(quota)s GiB Used" msgstr "%(used)s of %(quota)s GiB Used" #, python-format msgid "%(used)s of %(quota)s Used" msgstr "%(used)s of %(quota)s Used" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(Kuota terlampaui)" msgid "Access Key" msgstr "Access Key (kunci akses)" msgid "Access Level" msgstr "Access Level (tingkat akses)" msgid "Access Rules" msgstr "Access Rules" msgid "Access To" msgstr "Access To (akses ke)" msgid "Access Type" msgstr "Access Type (tipe akses)" msgid "Access to" msgstr "Access to (akses ke)" msgctxt "Current status of share network" msgid "Active" msgstr "Active (aktif)" msgctxt "Current status of share server" msgid "Active" msgstr "Active (aktif)" msgid "Add" msgstr "Add (tambah)" msgid "Add Rule" msgstr "Add Rule (tambah aturan)" msgid "Add Security Service" msgstr "Add Security Service (tambah layanan keamanan)" msgid "Add Share Snapshot Rule" msgstr "Menambahkan Share Snapshot Rule" msgid "" "Add policy rule to snapshot, 'ip' rule represents ip address, 'user' rule " "represents username or usergroup, 'cephx' rule represents ceph auth ID, and " "'cert' rule represents certificate." msgstr "" "Tambahkan aturan kebijakan ke snapshot, aturan 'ip' mewakili alamat ip, " "aturan 'user' mewakili nama pengguna atau grup pengguna, aturan 'cephx' " "mewakili ID otentikasi ceph, dan aturan 'cert' mewakili sertifikat." msgid "Add rule" msgstr "Tambah aturan" msgid "Add security services to share network." msgstr "Menambahkan layanan keamanan untuk jaringan berbagi." msgid "All keys and values must be in range from 1 to 255." msgstr "Semua key dan nilai-nilai harus dalam kisaran 1 sampai 255." msgid "All pairs that are in field for left are set for this metadata." msgstr "Semua pasangan yang ada di field kiri ditetapkan untuk metadata ini." msgid "All pairs that are in field for left are set for this share group type." msgstr "Semua pasang yang ada di field kiri ditetapkan untuk tipe share group." msgid "All pairs that are in field for left are set for this share type." msgstr "Semua pasang yang ada di field kiri ditetapkan untuk tipe berbagi ini." msgid "Allow project access to share group type." msgstr "Izinkan akses proyek ke share group type." msgid "Allow project access to share type." msgstr "Membolehkan akses proyek untuk tipe share." msgid "At least one security service must be specified." msgstr "Setidaknya satu layanan keamanan harus ditentukan." msgid "At least one share type must be specified." msgstr "Setidaknya satu share type harus ditentukan." msgid "Availability Zone" msgstr "Availability Zone (zona ketersediaan)" msgid "Availability zone" msgstr "Zona ketersediaan" msgctxt "Current status of replica" msgid "Available" msgstr "Available (tersedia)" msgctxt "Current status of share" msgid "Available" msgstr "Available (tersedia)" msgctxt "Current status of snapshot" msgid "Available" msgstr "Available (tersedia)" msgid "Available networks" msgstr "Jaringan yang tersedia" msgid "Available projects" msgstr "Proyek yang tersedia" msgid "Available security services" msgstr "Layanan keamanan yang tersedia" msgid "Cancel" msgstr "Cancel" msgid "Cancel Migration" msgstr "Cancel Migration (pembatalan migrasi)" msgid "Cancel migration" msgstr "Membatalkan migrasi" msgid "Cancel migration of a Share" msgstr "Pembatalan migrasi share " msgid "" "Cancel migration of a migrating share.

This is equivalent to the " "'manila migration-cancel' command." msgstr "" "Batalkan migrasi dari bagian yang bermigrasi.

Ini sama dengan " "perintah 'manila migration-cancel' ." msgid "Choose a snapshot" msgstr "Pilih snapshot" msgid "Complete Migration" msgstr "Complete Migration (menyelsaikan migrasi)" msgid "Complete migration" msgstr "Migrasi lengkap" msgid "Complete migration of a Share" msgstr "Menyelesaikan migrasi share" msgid "" "Complete migration of a migrating share to another Manila host. This " "operation is expected to be disruptive.

This is equivalent to the " "'manila migration-complete' command." msgstr "" "Migrasi lengkap dari bagian yang bermigrasi ke host lain di Manila. Operasi " "ini diperkirakan akan mengganggu.

Ini sama dengan perintah " "'manila migrasi-complete' ." msgid "Confirm Migration Cancelling of Share" msgstr "" "Confirm Migration Cancelling of Share (mengkonfirmasi pembatalan migrasi " "share)" msgid "Confirm Migration Completion of Share" msgstr "" "Confirm Migration Completion of Share (mengkonfirmasi penyelesaian migrasi " "share)" msgid "Confirm Obtaining migration progress of Share" msgstr "Konfirmasi perolehan kemajuan migrasi share" msgid "Confirm Password" msgstr "Confirm Password (konfirmasi sandi)" msgid "Confirm Unmanage Share" msgstr "Confirm Unmanage Share (Konfirmasi share yang tidak dikelola)" msgid "Create" msgstr "Create (buat)" msgid "Create Group Share Type" msgstr "Create Group Share Type" msgid "Create Replica" msgstr "Create Replica (buat replika)" msgid "Create Security Service" msgstr "Create Security Service (buat layanan keamanan)" msgid "Create Share" msgstr "Create Share (buat share)" msgid "Create Share Group" msgstr "Membuat Share Group" msgid "Create Share Group Snapshot" msgstr "Membuat Share Group Snapshot" msgid "Create Share Group Type" msgstr "Membuat Share Group Type" msgid "Create Share Network" msgstr "Create Share Network (Buat jaringan berbagi)" msgid "Create Share Replica" msgstr "Create Share Replica" msgid "Create Share Snapshot" msgstr "Create Share Snapshot (buat snapshot berbagi)" msgid "Create Share Type" msgstr "Create Share Type (membuat tipe share)" msgid "Create a Share" msgstr "Create a Share (Buat share)" msgid "Create share replica in specific availability zone." msgstr "Buat replika berbagi di zona ketersediaan tertentu." msgid "Created" msgstr "Created" msgid "Created At" msgstr "Created At" msgid "Created at" msgstr "Dibuat di" msgctxt "Current status of replica" msgid "Creating" msgstr "Creating (Pembuatan)" msgctxt "Current status of share" msgid "Creating" msgstr "Creating (pembuatan)" msgctxt "Current status of share server" msgid "Creating" msgstr "Creating (pembuatan)" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Creating (pembuatan)" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Menciptakan replika untuk berbagi \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Membuat aturan untuk \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Pembuatan share \"%s\"" #, python-format msgid "Creating share group \"%s\"" msgstr "Membuat share group \"%s\"" #, python-format msgid "Creating share group snapshot \"%s\"." msgstr "Membuat share group snapshot \"%s\"." #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Pembuatan snapshot berbagi \"%s\"." #, python-format msgid "Creating snapshot rule for \"%s\"" msgstr "Membuat aturan snapshot untuk \"%s\"" msgid "Current Size (GiB)" msgstr "Current Size (ukuran saat ini) (GiB)" msgid "DNS IP" msgstr "DNS IP" msgid "Delete Replica" msgid_plural "Delete Replicas" msgstr[0] "Delete Replica" msgid "Delete Rule" msgid_plural "Delete Rules" msgstr[0] "Delete Rule" msgid "Delete Security Service" msgid_plural "Delete Security Services" msgstr[0] "Delete Security Service" msgid "Delete Share" msgid_plural "Delete Shares" msgstr[0] "Delete Share" msgid "Delete Share Group" msgid_plural "Delete Share Groups" msgstr[0] "Delete Share Group" msgid "Delete Share Group Snapshot" msgid_plural "Delete Share Group Snapshots" msgstr[0] "Delete Share Group Snapshot" msgid "Delete Share Group Type" msgid_plural "Delete Share Group Types" msgstr[0] "Delete Share Group Type" msgid "Delete Share Network" msgid_plural "Delete Share Networks" msgstr[0] "Delete Share Network" msgid "Delete Share Server" msgid_plural "Delete Share Server" msgstr[0] "Delete Share Server" msgid "Delete Share Snapshot" msgid_plural "Delete Share Snapshots" msgstr[0] "Delete Share Snapshot" msgid "Delete Share Snapshot Rule" msgid_plural "Delete Share Snapshot Rules" msgstr[0] "Delete Share Snapshot Rule" msgid "Delete Share Type" msgid_plural "Delete Share Types" msgstr[0] "Delete Share Type" msgid "Delete Snapshot" msgid_plural "Delete Snapshots" msgstr[0] "Delete Snapshot" msgid "Deleted Replica" msgid_plural "Deleted Replicas" msgstr[0] "Deleted Replica" msgid "Deleted Rule" msgid_plural "Deleted Rules" msgstr[0] "Deleted Rule" msgid "Deleted Security Service" msgid_plural "Deleted Security Services" msgstr[0] "Deleted Security Service" msgid "Deleted Share" msgid_plural "Deleted Shares" msgstr[0] "Deleted Share" msgid "Deleted Share Group" msgid_plural "Deleted Share Groups" msgstr[0] "Deleted Share Group" msgid "Deleted Share Group Snapshot" msgid_plural "Deleted Share Group Snapshots" msgstr[0] "Deleted Share Group Snapshot" msgid "Deleted Share Group Type" msgid_plural "Deleted Share Group Types" msgstr[0] "Deleted Share Group Type" msgid "Deleted Share Network" msgid_plural "Deleted Share Networks" msgstr[0] "Deleted Share Network" msgid "Deleted Share Server" msgid_plural "Deleted Share Server" msgstr[0] "Deleted Share Server" msgid "Deleted Share Snapshot" msgid_plural "Deleted Share Snapshots" msgstr[0] "Deleted Share Snapshot" msgid "Deleted Share Snapshot Rule" msgid_plural "Deleted Share Snapshot Rules" msgstr[0] "Deleted Share Snapshot Rule" msgid "Deleted Share Type" msgid_plural "Deleted Share Types" msgstr[0] "Deleted Share Type" msgid "Deleted Snapshot" msgid_plural "Deleted Snapshots" msgstr[0] "Deleted Snapshot" msgctxt "Current status of replica" msgid "Deleting" msgstr "Deleting" msgctxt "Current status of share" msgid "Deleting" msgstr "Deleting (penghapusan)" msgid "Description" msgstr "Deskripsi" msgid "Description:" msgstr "Deskripsi:" msgid "Destination host and pool where share will be migrated to." msgstr "Host tujuan dan ke kolam dimana share akan bermigrasi." msgid "Domain" msgstr "Domain" msgid "Driver handles share servers" msgstr "Driver menangani server share" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Opsi driver ('volume_id' untuk driver Generic, dll ...)" #, python-format msgid "Duplicated keys '%s'." msgstr "Key duplikat '%s'." msgid "Edit" msgstr "Edit (perbaharui)" msgid "Edit Security Service" msgstr "Edit Security Service (perbaharui layanan keamanan)" msgid "Edit Share" msgstr "Edit Share (perbaharui share)" msgid "Edit Share Metadata" msgstr "Edit Share Metadata (mengedit metadata berbagi)" msgid "Edit Share Network" msgstr "Edit Share Network (mengedit jaringan berbagi)" msgid "Edit Share Snapshot" msgstr "Edit Share Snapshot" msgid "Edit Share network" msgstr "Edit jaringan berbagi" msgid "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgstr "" "Memberlakukan migrasi dari snapshot share ke tujuan. Jika diatur ke True, " "migrasi host-assisted tidak akan diusahakan." msgid "" "Enforces migration to be nondisruptive. If set to True, host-assisted " "migration will not be attempted." msgstr "" "Memberlakukan migrasi menjadi nondisruptive. Jika diatur ke True, migrasi " "host-assisted tidak akan diusahakan." msgid "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgstr "" "Memberlakukan migrasi untuk menjaga share dapat ditulis sementara isinya " "dipindahkan. Jika diatur ke True, migrasi host-assisted tidak akan " "diusahakan." msgid "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgstr "" "Memberlakukan migrasi untuk melestarikan semua metadata file yang ketika " "bergerak isinya. Jika diatur ke True, migrasi host-assisted tidak akan " "diusahakan." msgid "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimizations." msgstr "" "Memberlakukan penggunaan pendekatan migrasi host-assisted, yang melewati " "optimasi driver." msgctxt "Current status of replica" msgid "Error" msgstr "Error (kesalahan)" msgctxt "Current status of share" msgid "Error" msgstr "Error (kesalahan)" msgctxt "Current status of share network" msgid "Error" msgstr "Error (kesalahan)" msgctxt "Current status of share server" msgid "Error" msgstr "Error (kesalahan)" msgctxt "Current status of snapshot" msgid "Error" msgstr "Error (kesalahan)" msgid "Expected only pairs of key=value." msgstr "Diharapkan hanya pasang key=value." msgid "Export location" msgstr "Lokasi ekspor" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "Lokasi ekspor share. misalnya untuk NFS: 1.2.3.4:/path/to/share" msgid "Export locations" msgstr "Lokasi ekspor" msgctxt "Current status of share" msgid "Extending Error" msgstr "Extending Error (kesalahan meluas)" msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "Extra spec 'driver_handles_share_servers' diperlukan dan harus memiliki " "nilai boolean." msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "Ekstra spec 'driver_handles_share_servers' diperlukan dan harus memiliki " "nilai boolean." msgid "Extra specs" msgstr "Spesifikasi tambahan" msgid "Force Host Assisted Migration" msgstr "Force Host Assisted Migration" msgid "From here you can modify name and description of a security service." msgstr "Dari sini Anda bisa memodifikasi nama dan deskripsi layanan keamanan." msgid "" "From here you can modify name and description of a share group snapshot." msgstr "" "Dari sini Anda dapat memodifikasi nama dan deskripsi dari sebuah snapshot " "kelompok saham." msgid "From here you can modify name and description of a share network." msgstr "Dari sini Anda bisa memodifikasi nama dan deskripsi jaringan berbagi." msgid "From here you can modify name and description of a snapshot." msgstr "Dari sini Anda bisa memodifikasi nama dan deskripsi sebuah snapshot." msgid "" "From here you can modify name, description and visibility of a share group." msgstr "" "Dari sini Anda dapat memodifikasi nama, deskripsi dan visibilitas grup " "berbagi." msgid "From here you can modify name, description and visibility of a share." msgstr "" "Dari sini Anda dapat mengubah nama, deskripsi dan visibilitas suatu share." msgid "From here you can revert the share to its latest snapshot." msgstr "Dari sini Anda dapat mengembalikan share ke snapshot terbarunya." msgid "From here you can update share network info. " msgstr "Dari sini Anda dapat memperbarui informasi jaringan berbagi." msgid "From here you can update the default share quotas (max limits)." msgstr "Dari sini Anda dapat memperbarui kuota share default (batas maksimal)." msgid "Get Migration Progress" msgstr "Get Migration Progress" msgid "Get migration progress" msgstr "Dapatkan kemajuan migrasi" msgid "GiB" msgstr "GiB" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "Punya nilai yang tidak benar untuk kolom 'driver_options'. Diharapkan hanya " "pasangan kunci = nilai (key=value)" msgid "Group specs" msgstr "Group specs" msgid "Here can be modified extra-specs for share type." msgstr "Disini bisa dimodifikasi extra-specs untuk tipe berbagi." msgid "Here can be modified group-specs for share group type." msgstr "Disini bisa dimodifikasi group-specs untuk share group type." msgid "Host" msgstr "Host" msgid "Host of share" msgstr "Host share" msgid "Host to migrate share" msgstr "Host memigrasikan share" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "Host dimana share berada, misalnya: some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "IP Version" msgid "Id" msgstr "Id" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "Pengaturan nilai yang tidak benar untuk spesifikasi tambahan yang " "diperlukan 'spec_driver_handles_share_servers'. Nilai yang diperbolehkan " "adalah %s. Case insensitive." msgctxt "Current status of share server" msgid "In-use" msgstr "In-use" msgctxt "Current status of snapshot" msgid "In-use" msgstr "In-use" msgctxt "Current status of share network" msgid "Inactive" msgstr "Inactive (tidak aktif)" #, python-format msgid "Key '%s' has improper length." msgstr "Key '%s' memiliki panjang yang tidak benar." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Key tidak bisa berisi spasi. Lihat string '%s'." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Key harus tidak mengandung spasi. Kesalahan dalam '%s'." msgid "Limit" msgstr "Limit" msgid "Manage" msgstr "Manage (mengelola)" msgctxt "Current status of share" msgid "Manage Error" msgstr "Manage Error (mengelola kesalahan)" msgid "Manage Replicas" msgstr "Manage Replicas (mengelola replika)" msgid "Manage Rules" msgstr "Manage Rules (mengelola aturan)" msgid "Manage Share" msgstr "Manage Share (mengelola share)" msgid "Manage Share Group Type Access" msgstr "Mengelola Share Group Type Access" msgid "Manage Share Snapshot Rules" msgstr "Mengelola Share Snapshot Rules" msgid "Manage Share Type Access" msgstr "Manage Share Type Access (mengelola akses tipe share)" msgid "Metadata" msgstr "Metadata" msgid "Migrate Share" msgstr "Migrate Share (migrasi share)" msgid "Migrate a Share" msgstr "Migrate a Share (memigrasi share)" msgid "" "Migrate an existing share to another Manila host. This will move all your " "share data from one host to another.

This is equivalent to the " "'manila migration-start' command." msgstr "" "Bermigrasi bagian yang ada ke host lain di Manila. Ini akan memindahkan " "semua data berbagi Anda dari satu host ke host lain.

Ini sama " "dengan perintah 'manila migration-start' ." msgctxt "Current status of share" msgid "Migrating" msgstr "Migrating (migrasi)" msgctxt "Current status of share" msgid "Migrating to" msgstr "Bermigrasi ke" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "Migrasi dari share %(name)s berada pada %(progress)s persen." msgid "Mount snapshot support" msgstr "Dukungan mount snapshot" msgid "Name" msgstr "Name (nama)" msgid "Net Details" msgstr "Net Details" msgid "Network" msgstr "Network" msgid "Network Type" msgstr "Network Type (tipe jaringan)" msgid "Networks" msgstr "Networks (jaringan)" msgid "Neutron Net" msgstr "Neutron Net" msgid "Neutron Subnet" msgstr "Neutron Subnet (subnet Neutron)" msgid "New Size (GiB)" msgstr "New Size (ukuran baru) (GiB)" msgid "New share network to be set in migrated share" msgstr "Jaringan share baru yang akan ditetapkan di share bermigrasi" msgid "New share type to be set in migrating share" msgstr "Jenis share baru yang akan diatur dalam migrasi share" msgid "No projects found." msgstr "Tidak ada proyek yang ditemukan." msgid "No projects selected." msgstr "Tidak ada proyek yang dipilih." msgid "No security services found." msgstr "Tidak ada layanan keamanan ditemukan." msgid "No security services selected." msgstr "Tidak ada layanan keamanan yang dipilih." msgid "No source, empty share" msgstr "Tidak ada sumber, share kosong" msgid "No source, empty share group" msgstr "Tidak ada sumber, kosong share group" msgid "Nondisruptive" msgstr "Nondisruptive" msgid "Number of Share Snapshots" msgstr "Number of Share Snapshots" msgid "Number of Shares" msgstr "Number of Shares" msgid "Obtain Progress" msgstr "Obtain Progress (mendapatkan kemajuan)" msgid "Obtain migration progress of a Share" msgstr "Mendapatkan kemajuan migrasi share" msgid "" "Obtains migration progress of a migrating share.

This is " "equivalent to the 'manila migration-get-progress' command." msgstr "" "Dapatkan kemajuan migrasi dari bagian yang bermigrasi.

Ini sama " "dengan perintah 'manila migration-get-progress' ." msgid "One line - one action. Empty strings will be ignored." msgstr "One line - one action. String kosong akan diabaikan." msgid "Overview" msgstr "Overview (ikhtisar)" msgid "Password" msgstr "Password (sandi)" msgid "Passwords do not match." msgstr "Sandi tidak cocok" msgid "Placeholder for description of share group type access managing form." msgstr "" "Placeholder untuk deskripsi bentuk pengelolaan akses tipe grup berbagi." msgid "Placeholder for description of share type access managing form." msgstr "Placeholder untuk deskripsi bentuk pengelolaan akses tipe berbagi." msgid "Preserve Metadata" msgstr "Preserve Metadata (pertahankan metadata)" msgid "Preserve Snapshots" msgstr "Preserve Snapshots" msgid "Project" msgstr "Project (proyek)" msgid "Projects with access to share group type" msgstr "Proyek dengan akses keshare group type" msgid "Projects with access to share type" msgstr "Proyek dengan akses untuk tipe share" msgid "Protocol" msgstr "Protocol (protokol)" msgid "Public" msgstr "Public (publik)" msgid "Quota Name" msgstr "Quota Name" msgid "Replica Details" msgstr "Replica Details" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Rincian replika: %(replica_display_name)s" msgid "Replica State" msgstr "Replica State (keadaan replika)" msgid "Replica state" msgstr "Replica state" msgid "Replicas" msgstr "Replicas (replika)" msgid "Reset Replica State" msgstr "Reset Replica State (mengatur ulang keadaan replika)" msgid "Reset Replica Status" msgstr "Reset Replica Status (menyetel ulang status replika)" msgid "Reset Share Group Snapshot Status" msgstr "Reset Share Group Snapshot Status" msgid "Reset Share Group Status" msgstr "Reset Share Group Status" msgid "Reset Status" msgstr "Reset Status" msgid "Reset replica state" msgstr "Mengatur ulang keadaan replika" msgid "Reset replica status" msgstr "Mengatur ulang status replika" msgid "Reset share replica's state with ID" msgstr "Setel ulang status replika berbagi dengan ID" msgid "Reset share replica's status with ID" msgstr "Setel ulang status replika berbagi dengan ID" msgid "Reset state" msgstr "Reset state (mengatur slang status)" msgid "Reset status" msgstr "Mengatur ulang status" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "Atur ulang replika ('%(id)s') keadaan dari '%(from)s' ke '%(to)s'." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "Atur ulang replika ('%(id)s') status dari '%(from)s' ke'%(to)s'." #, python-format msgid "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Menyetel ulang status share group ('%(id)s') dari '%(from)s' ke '%(to)s'." #, python-format msgid "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Menyetel ulang status share group snapshot ('%(id)s') dari '%(from)s' ke " "'%(to)s'." msgid "Resync" msgstr "Resync" msgid "Resync Replica" msgstr "Resync Replica" msgid "Resync replica" msgstr "Resync replika" msgid "Resync share replica with ID" msgstr "Resync (resinkronkan) replika berbagi dengan ID" #, python-format msgid "Resync'ing replica '%s'" msgstr "Resync'ing replika '%s'" msgid "Revert Share" msgstr "Kembalikan Berbagi" msgid "Revert Share to a Snapshot" msgstr "Kembalikan Berbagi ke Snapshot" msgid "Revert share to a snapshot" msgstr "Kembalikan berbagi ke snapshot" msgctxt "Current status of share" msgid "Reverting Error" msgstr "Mengembalikan Kesalahan" msgid "Rules" msgstr "Rules (aturan)" msgid "Save Changes" msgstr "Save Changes (simpan perubahan)" msgid "Security Service Details" msgstr "Security Service Details " #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Rincian layanan keamanan: %(service_display_name)s" msgid "Security Service Overview" msgstr "Security Service Overview" msgid "Security Services" msgstr "Security Services (layanan keamanan)" msgid "Security services within share network" msgstr "layanan keamanan dalam jaringan berbagi" msgid "Segmentation Id" msgstr "Segmentation Id (segmentasi Id)" msgid "Select parameters of share group you want to create. " msgstr "Pilih parameter dari grup berbagi yang ingin Anda buat." msgid "Select parameters of share you want to create. " msgstr "Pilih parameter share yang ingin Anda buat." msgid "Selected Networks" msgstr "Selected Networks" msgid "Selected Projects" msgstr "Selected Projects" msgid "Selected projects" msgstr "Proyek yang dipilih" msgid "Selected security services" msgstr "layanan keamanan terpilih" msgid "Server" msgstr "Server" msgid "Set Replica as Active" msgstr "Menetapkan replika menjadi aktif" msgid "Set as Active" msgstr "Set as Active (Atur ke aktif)" msgid "Set maximum quotas for the project." msgstr "Menetapkan kuota maksimum untuk proyek tersebut." msgid "Set share replica with ID" msgstr "Tetapkan replika berbagi dengan ID" #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Pengaturan replika \"%s\" aktif ..." msgid "Share" msgstr "Share" #, python-format msgid "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgstr "Berbagi \"%(s)s\" has been reverted to \"%(ss)s\" snapshot berhasil" msgid "Share Details" msgstr "Share Details" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Share Details (rincian share): %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Rincian share: %(share_name)s" msgid "Share Group" msgstr "Share Group" msgid "Share Group Details" msgstr "Share Group Details" #, python-format msgid "Share Group Details: %s" msgstr "Share Group Details: %s" msgid "Share Group Name" msgstr "Share Group Name" msgid "Share Group Overview" msgstr "Share Group Overview" msgid "Share Group Snapshot" msgstr "Share Group Snapshot" msgid "Share Group Snapshot Details" msgstr "Share Group Snapshot Details" #, python-format msgid "Share Group Snapshot Details: %(sgs_display_name)s" msgstr "Share Group Snapshot Details: %(sgs_display_name)s" msgid "Share Group Snapshot Overview" msgstr "Share Group Snapshot Overview" msgid "Share Group Snapshots" msgstr "Share Group Snapshots" msgid "Share Group Type" msgstr "Share Group Type" msgid "Share Group Types" msgstr "Share Group Types" msgid "Share Groups" msgstr "Share Groups" msgid "Share ID" msgstr "Share ID" msgid "Share Instance Details" msgstr "Share Instance Details" #, python-format msgid "Share Instance Details: %s" msgstr "Share Instance Details (rincian instance berbagai): %s" msgid "Share Instance Overview" msgstr "Share Instance Overview" msgid "Share Instances" msgstr "Share Instances (instance berbagi)" msgid "Share Limits" msgstr "Share Limits" msgid "Share Name" msgstr "Share Name" msgid "Share Network" msgstr "Share Network (jaringan berbagi)" msgid "Share Network Details" msgstr "Share Network Details" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "" "Share Network Details (rincian jaringan berbagi): %(network_display_name)s" msgid "Share Network Info" msgstr "Share Network Info (info jaringan berbagi)" msgid "Share Network Overview" msgstr "Share Network Overview" msgid "Share Networks" msgstr "Share Networks (jaringan berbagi)" msgid "Share Overview" msgstr "Share Overview" msgid "Share Protocol" msgstr "Share Protocol (protokol share)" msgid "Share Quotas" msgstr "Share Quotas" msgid "Share Replica Overview" msgstr "Share Replica Overview" msgid "Share Replicas" msgstr "Share Replicas (replika berbagi)" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr " Replika berbagi: %(share_display_name)s" msgid "Share Rules" msgstr "Share Rules" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Share Rules (aturan share): %(share_display_name)s" msgid "Share Server" msgstr "Share Server" msgid "Share Server Details" msgstr "Share Server Details" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Share Server Details (rincian server berbagi): %(server_name)s" msgid "Share Server Id" msgstr "Share Server Id" msgid "Share Server Overview" msgstr "Share Server Overview" msgid "Share Servers" msgstr "Share Servers (server berbagi)" msgid "Share Snapshot Details" msgstr "Share Snapshot Details" msgid "Share Snapshot Name" msgstr "Share Snapshot Name" msgid "Share Snapshot Overview" msgstr "Share Snapshot Overview" msgid "Share Snapshot Rules" msgstr "Share Snapshot Rules" msgid "Share Snapshots" msgstr "Share Snapshots (snapshots bersama)" msgid "Share Snapshots Storage" msgstr "Share Snapshots Storage (penyimpanan snapshot bersama)" msgid "" "Share Snapshots are used for storing share changes and creating shares. " msgstr "" "Share Snapshots digunakan untuk menyimpan perubahan share dan membuat share." msgid "Share Source" msgstr "Share Source (berbagi sumber)" msgid "Share Storage" msgstr "Share Storage (penyimpanan bersama)" msgid "Share Type" msgstr "Share Type (tipe share)" msgid "Share Types" msgstr "Share Types (tipe share)" msgid "Share Types (multiple available)" msgstr "Share Types (multiple available)" msgid "Share Types (one available)" msgstr "Share Types (one available)" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Share tidak dapat diperpanjang untuk %(req)iGiB karena Anda hanya memiliki " "%(avail)iGiB dari kuota Anda yang tersedia." msgid "Share gigabytes" msgstr "Berbagi gigabyte" msgid "Share name to be assigned" msgstr "Nama share yang akan ditetapkan" msgid "Share network" msgstr "Bagikan jaringan" msgid "" "Share networks contain network data, that will be used for creation of " "service VM, where will be hosted shares." msgstr "" "Jaringan berbagi berisi data jaringan, yang akan digunakan untuk pembuatan " "VM layanan, tempat berbagi host." #, python-format msgid "Share replica %s has been deleted." msgstr "Berbagi replika %s sudah dihapus." msgid "Share server" msgstr "Bagikan server" #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "" "Ukuran berbagi (share size) harus sama atau lebih besar dari ukuran snapshot " "(%sGiB)" msgid "Share snapshot gigabytes" msgstr "Berbagi snapshot gigabyte" msgid "Share snapshots" msgstr "Berbagi snapshot" msgid "Share type" msgstr "Share type" msgid "Share types" msgstr "Share types" msgid "Shared Quotas" msgstr "Shared Quotas" msgid "Shares" msgstr "Shares" msgid "Shares on this server" msgstr "Berbagi di server ini" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Size (ukuran)" msgid "Size (GiB)" msgstr "Size (GiB)" msgid "Snapshot" msgstr "Snapshot" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Snapshot Details (rincian snapshot) : %(snapshot_display_name)s" msgid "Snapshot ID" msgstr "Snapshot ID" msgid "Snapshot Overview" msgstr "Snapshot Overview (ikhtisar snapshot)" #, python-format msgid "Snapshot Rules: %(snapshot_display_name)s" msgstr "Snapshot Rules (aturan snapshot): %(snapshot_display_name)s" msgid "Source" msgstr "Source (sumber)" msgid "Source SG Snapshot" msgstr "Source SG Snapshot" msgid "Source Share Group" msgstr "Source Share Group" msgid "Source Share Group Snapshot" msgstr "Source Share Group Snapshot" msgid "Source Type" msgstr "Source Type" msgid "Source share group snapshot" msgstr "Snapshot kelompok berbagi sumber" msgid "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgstr "" "Tentukan jaringan share baru untuk berbagi. Jangan menentukan parameter ini " "jika share yang bermigrasi harus dipertahankan dalam jaringan share saat ini." msgid "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgstr "" "Tentukan tipe share baru untuk berbagi. Tidak menentukan parameter ini jika " "share yang bermigrasi harus dipertahankan dengan tipe share saat ini." msgid "Specs" msgstr "Specs" msgid "Start migration" msgstr "Start migration (memulai migrasi)" msgid "Status" msgstr "Status" msgid "Submit" msgstr "Submit" msgid "Subnet" msgstr "Subnet" #, python-format msgid "Successfully created security service: %s" msgstr "Berhasil menciptakan layanan keamanan: %s" #, python-format msgid "Successfully created share group type: %s" msgstr "Berhasil membuat share group type: %s" #, python-format msgid "Successfully created share network: %s" msgstr "Berhasil menciptakan jaringan bersama (share) :%s" #, python-format msgid "Successfully created share type: %s" msgstr "Berhasil menciptakan tipe share: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "Berhasil mengirim permintaan untuk membatalkan migrasi share: %s." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "Berhasil dikirim permintaan untuk menyelesaikan migrasi share: %s." #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Berhasil dikirim permintaan untuk mengelola share: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "Berhasil dikirim permintaan memigrasikan share: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "" "Berhasil mengirimkan permintaan untuk tidak mengelola (unmanaged) share: %s" #, python-format msgid "Successfully updated group specs for share group type '%s'." msgstr "Spesifikasi grup yang berhasil diperbarui untuk share group type '%s'." #, python-format msgid "Successfully updated security service \"%s\"" msgstr "layanan keamanan berhasil diperbarui \"%s\"" msgid "Task state" msgstr "Status tugas" msgid "" "The security service can be used by backend drivers to configure clients, " "for more secure using of share." msgstr "" "Layanan keamanan dapat digunakan oleh driver backend untuk mengkonfigurasi " "klien, untuk penggunaan berbagi yang lebih aman." msgid "" "The share group type defines the characteristics of a share group backend." msgstr "Tipe share groupi mendefinisikan karakteristik share group backend." #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "" "Ukuran berbagi (share size) tidak bisa kurang dari ukuran snapshot (%sGiB)" msgid "The share type defines the characteristics of a share backend." msgstr "Tipe share mendefinisikan karakteristik share backend." msgid "To add extra-specs use:" msgstr "Untuk menambahkan penggunaan extra-specs:" msgid "To add group-specs use:" msgstr "Untuk menambahkan penggunaan group-specs:" msgid "To add metadata use:" msgstr "Untuk menambahkan penggunaan metadata:" msgid "To unset extra-specs use:" msgstr "Untuk tidak mengatur penggunaan extra-specs:" msgid "To unset group-specs use:" msgstr "Untuk tak mengatur penggunaan group-specs:" msgid "To unset metadata use:" msgstr "Untuk tanpa mengatur penggunaan metadata:" msgid "Total Gibibytes" msgstr "Total Gibibytes" msgid "Type" msgstr "Type (tipe)" msgid "Unable to add rule." msgstr "Tidak dapat menambahkan aturan." msgid "Unable to add snapshot rule." msgstr "Tidak dapat menambahkan aturan snapshot." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "Tidak dapat membatalkan migrasi share %s saat ini." #, python-format msgid "Unable to complete migration of share %s." msgstr "Tidak dapat menyelesaikan migrasi share %s." msgid "Unable to create security service." msgstr "Tidak dapat membuat layanan keamanan." msgid "Unable to create share group snapshot." msgstr "Tidak dapat membuat share group snapshot." msgid "Unable to create share group type." msgstr "Tidak dapat membuat share group type." msgid "Unable to create share group." msgstr "Tidak dapat membuat share group." msgid "Unable to create share network." msgstr "Tidak dapat membuat jaringan berbagi (share)." msgid "Unable to create share replica." msgstr "Tidak dapat membuat replika share." msgid "Unable to create share snapshot." msgstr "Tidak dapat membuat snapshot berbagi." msgid "Unable to create share type." msgstr "Tidak dapat membuat tipe share" msgid "Unable to create share." msgstr "Tidak dapat membuat share." #, python-format msgid "Unable to create share. %s" msgstr "Tidak dapat membuat share. %s" #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Tidak dapat menghapus replika \"%s\"." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Tidak dapat menghapus aturan \"%s\"." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Tidak dapat menghapus share \"%s\". " #, python-format msgid "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." msgstr "" "Tidak dapat menghapus share group snapshot \"%s\". Satu atau lebih share " "group bergantung padanya." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "Tidak dapat menghapus snapshot \"%s\". Satu atau lebih share bergantung " "padanya." #, python-format msgid "Unable to delete snapshot rule \"%s\"." msgstr "Tidak dapat menghapus aturan snapshot \"%s\"." msgid "Unable to get information about share group type access." msgstr "Tidak dapat memperoleh informasi tentang share group type access." msgid "Unable to get information about share type access." msgstr "Tidak dapat mendapatkan informasi tentang akses tipe share." msgid "Unable to get list of projects." msgstr "Tidak dapat mendapatkan daftar proyek." msgid "Unable to get manila default quota." msgstr "Tidak dapat memperoleh kuota default manila." msgid "Unable to get the security services hosts" msgstr "Tidak dapat mendapatkan host layanan keamanan" #, python-format msgid "Unable to get the specified share group '%s' for snapshot creation." msgstr "" "Tidak dapat memperoleh share group yang ditentukan '%s' untuk pembuatan " "snapshot." msgid "Unable to load the specified share group snapshot." msgstr "Tidak dapat memuat share group snapshot yang ditentukan." msgid "Unable to load the specified snapshot." msgstr "Tidak dapat memuat snapshot spesifik." msgid "Unable to manage share" msgstr "Tidak mampu mengelola share" #, python-format msgid "Unable to migrate share %s." msgstr "Tidak dapat bermigrasi share %s." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "Tidak dapat memperoleh kemajuan migrasi share %s saat ini." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "Tidak dapat mengatur ulang keadaan replika '%s'." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "Tidak dapat mengatur ulang status replika '%s'." #, python-format msgid "Unable to reset status of share group '%s'." msgstr "Tidak dapat mengatur ulang status share group '%s'." #, python-format msgid "Unable to reset status of share group snapshot '%s'." msgstr "Tidak dapat mengatur ulang status share group snapshot '%s'." #, python-format msgid "Unable to resync replica '%s'." msgstr "Tidak dapat resync replika '%s'." msgid "Unable to retrieve default share quotas." msgstr "Tidak dapat mengambil kuota share default." msgid "Unable to retrieve list of projects." msgstr "Tidak dapat mengambil daftar proyek." msgid "Unable to retrieve quotas." msgstr "Tidak dapat mengambil kuota." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Tidak dapat mengambil replika '%s'." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Tidak dapat mengambil layanan keamanan '%s' rincian." msgid "Unable to retrieve security services" msgstr "Tidak dapat mengambil layanan keamanan" msgid "Unable to retrieve security_service." msgstr "Tidak dapat mengambil security_service." msgid "Unable to retrieve share details." msgstr "Tidak dapat mengambil rincian saham." #, python-format msgid "Unable to retrieve share group '%s'." msgstr "Tidak dapat mengambil share group '%s'." msgid "Unable to retrieve share group details." msgstr "Tidak dapat mengambil share group details." #, python-format msgid "Unable to retrieve share group snapshot '%s'." msgstr "Tidak dapat mengambil share group snapshot '%s'." msgid "Unable to retrieve share group snapshot details." msgstr "Tidak dapat mengambil share group snapshot details." msgid "Unable to retrieve share group snapshot list." msgstr "Tidak dapat mengambil daftar share group snapshot." msgid "Unable to retrieve share group snapshot." msgstr "Tidak dapat mengambil share group snapshot." msgid "Unable to retrieve share group snapshots." msgstr "Tidak dapat mengambil share group snapshots." msgid "Unable to retrieve share group types." msgstr "Tidak dapat mengambil share group types." msgid "Unable to retrieve share group." msgstr "Tidak dapat mengambil share group." msgid "Unable to retrieve share groups." msgstr "Tidak dapat mengambil share groups." msgid "Unable to retrieve share instance details." msgstr "Tidak dapat mengambil rincian instance berbagi." msgid "Unable to retrieve share instances." msgstr "Tidak dapat mengambil instance berbagi." msgid "Unable to retrieve share limit information." msgstr "Tidak dapat mengambil informasi batas share." msgid "Unable to retrieve share list." msgstr "Tidak dapat mengambil daftar share." msgid "Unable to retrieve share network details." msgstr "Tidak dapat mengambil rincian jaringan berbagi." msgid "Unable to retrieve share network." msgstr "Tidak dapat mengambil jaringan berbagi." msgid "Unable to retrieve share networks" msgstr "Tidak dapat mengambil jaringan berbagi" msgid "Unable to retrieve share replicas." msgstr "Tidak dapat mengambil replika berbagi." msgid "Unable to retrieve share rules." msgstr "Tidak dapat mengambil aturan share." msgid "Unable to retrieve share server details." msgstr "Tidak dapat mengambil rincian server share." msgid "Unable to retrieve share servers" msgstr "Tidak dapat mengambil server berbagi" msgid "Unable to retrieve share snapshot list." msgstr "Tidak dapat mengambil daftar share snapshot." msgid "Unable to retrieve share snapshot rules." msgstr "Tidak dapat mengambil share snapshot rule." msgid "Unable to retrieve share snapshot." msgstr "Tidak dapat mengambil share snapshot." msgid "Unable to retrieve share snapshots list." msgstr "Tidak dapat mengambil daftar snapshot berbagi." msgid "Unable to retrieve share snapshots." msgstr "Tidak dapat mengambil snapshot berbagi." msgid "Unable to retrieve share types." msgstr "Tidak dapat mengambil share types." msgid "Unable to retrieve share." msgstr "Tidak dapat mengambil share." #, python-format msgid "Unable to retrieve share. %s" msgstr "Tidak dapat mengambil share. %s" msgid "Unable to retrieve share_gruop_type." msgstr "Tidak dapat mengambil share_gruop_type." msgid "Unable to retrieve share_type." msgstr "Tidak dapat mengambil share_type." msgid "Unable to retrieve snapshot details." msgstr "Tidak dapat mengambil rincian snapshot." msgid "Unable to retrieve snapshot." msgstr "Tidak dapat mengambil snapshot." msgid "Unable to retrieve volume details." msgstr "" "Unable to retrieve volume details. (tidak dapat mengambil rincian volume)" msgid "Unable to revert share to the snapshot." msgstr "Tidak dapat kembali berbagi dengan snapshot." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Tidak dapat mengatur replika '%s' aktif." msgid "Unable to unmanage share." msgstr "Tidak dapat tidak mengelola (unmanage) share." #, python-format msgid "Unable to update access for share group type \"%s\"." msgstr "Tidak dapat memperbarui akses untuk share group type \"%s\"." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Tidak dapat memperbarui akses untuk tipe share \"%s\"." msgid "Unable to update default quotas." msgstr "Tidak dapat memperbarui kuota default." msgid "Unable to update group_specs for share group type." msgstr "Tidak dapat memperbarui group_specs untuk share group type." msgid "Unable to update security service." msgstr "Tidak dapat memperbarui layanan keamanan." msgid "Unable to update share group snapshot." msgstr "Tidak dapat memperbarui share group snapshot." msgid "Unable to update share group type." msgstr "Tidak dapat memperbarui share group type." msgid "Unable to update share group." msgstr "Tidak dapat memperbarui share group." msgid "Unable to update share metadata." msgstr "Tidak dapat memperbarui metadata berbagi." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Tidak dapat memperbarui jaringan berbagi \"%s\"." msgid "Unable to update share network." msgstr "Tidak dapat memperbarui jaringan berbagi." msgid "Unable to update share snapshot." msgstr "Tidak dapat memperbarui share snapshot." msgid "Unable to update share type." msgstr "Tidak dapat memperbarui tipe share." msgid "Unable to update share." msgstr "Tidak dapat memperbarui share." msgid "Unknown" msgstr "Unknown (tidak diketahui)" msgid "Unmanage" msgstr "Unmanage (tidak dikelola)" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Unmanage Error (kesalahan tidak dikelola)" msgid "Unmanage Share" msgstr "Unmanage Share (share tidak terkelola)" msgid "Update" msgstr "Update (perbarui)" msgid "Update Share Group" msgstr "Memperbarui Share Group" msgid "Update Share Group Snapshot" msgstr "Memperbarui Share Group Snapshot" msgid "Update Share Group Type" msgstr "Update Share Group Type" msgid "Update Share Network" msgstr "Update Share Network (memperharui jaringan berbagi)" msgid "Update Share Snapshot" msgstr "Memperbarui Share Snapshot" msgid "Update Share Type" msgstr "Update Share Type (Memperbarui tipe share)" msgid "Update Share group Type" msgstr "Update Share group Type" msgid "Update share network" msgstr "Perbarui jaringan berbagi" msgid "Updated" msgstr "Diperbarui" msgid "Updated At" msgstr "Updated At" #, python-format msgid "Updated access for share group type \"%s\"." msgstr "Akses yang diperbarui untuk share group type \"%s\"." #, python-format msgid "Updated access for share type \"%s\"." msgstr "Diperbaharui akses untuk tipe share \"%s\"." #, python-format msgid "Updated share network \"%s\"." msgstr "Diperbarui jaringan berbagi \"%s\"." #, python-format msgid "Updating share \"%s\"" msgstr "Perbaharui share \"%s\"" #, python-format msgid "Updating share group \"%s\"" msgstr "Memperbarui share group \"%s\"" #, python-format msgid "Updating share group snapshot \"%s\"" msgstr "Memperbarui share group snapshot \"%s\"" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Memperbarui metadata berbagi \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Memperbarui jaringan berbagi \"%s\"" #, python-format msgid "Updating share snapshot \"%s\"" msgstr "Memperbarui share snapshot \"%s\"" msgid "Use share group snapshot as a source" msgstr "Menggunakan share group snapshot sebagai sumber" msgid "Use snapshot as a source" msgstr "Gunakan snapshot sebagai sumber" msgid "User" msgstr "User (pengguna)" msgid "Visibility" msgstr "Visibility (keterlihatan)" msgid "" "When a share is \"unmanaged\", the share will no longer be visible within " "OpenStack. Note that the share will not be deleted.

This is " "equivalent to the 'manila unmanage' command." msgstr "" "Ketika sebuah share \"unmanaged\", share tersebut tidak akan lagi terlihat " "di dalam OpenStack. Perhatikan bahwa pembagian tidak akan dihapus.

" "Ini sama dengan perintah 'manila unmanage' ." msgid "Writable" msgstr "Writable (dapat ditulis)" msgid "as Active?" msgstr "as Active?" msgid "key=value pairs per line can be set" msgstr "Pasasngan key=value per baris dapat diatur" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/ko_KR/0000775000175000017500000000000000000000000017672 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/ko_KR/LC_MESSAGES/0000775000175000017500000000000000000000000021457 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/ko_KR/LC_MESSAGES/django.po0000664000175000017500000014505300000000000023271 0ustar00zuulzuul00000000000000# Eunseop Shin , 2016. #zanata # Ian Y. Choi , 2016. #zanata # Sungjin Kang , 2017. #zanata # minwook-shin , 2017. #zanata # ByungYeol Woo , 2018. #zanata # Ian Y. Choi , 2018. #zanata # Sungjin Kang , 2018. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2018-10-21 07:06+0000\n" "Last-Translator: Sungjin Kang \n" "Language-Team: Korean (South Korea)\n" "Language: ko_KR\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "" "\"Manage\" an existing share from a Manila host. This will make the share " "visible within OpenStack.

This is equivalent to the 'manila " "manage' command." msgstr "" "Manila 호스트에서 기존 공유를 \"관리\"합니다. 이렇게하면 OpenStack에서 공유" "를 확인할 수 있습니다.

'manila manage' 명령과 동일합니다." #, python-format msgid "%(used)s of %(quota)s GiB Used" msgstr "%(quota)s 중 %(used)s GIB 사용됨" #, python-format msgid "%(used)s of %(quota)s Used" msgstr "%(quota)s 중 %(used)s 사용됨" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(Quota 초과)" msgid "Access Key" msgstr "접근 키" msgid "Access Level" msgstr "엑세스 레벨" msgid "Access Rules" msgstr "접속 규칙" msgid "Access To" msgstr "에 엑세스" msgid "Access Type" msgstr "엑세스 타입" msgid "Access to" msgstr "에 접근" msgctxt "Current status of share network" msgid "Active" msgstr "활성화됨" msgctxt "Current status of share server" msgid "Active" msgstr "활성화됨" msgid "Add" msgstr "추가" msgid "Add Rule" msgstr "규칙 추가" msgid "Add Security Service" msgstr "보안 서비스 추가" msgid "Add Share Snapshot Rule" msgstr "공유 스냅샷 규칙 추가" msgid "" "Add policy rule to snapshot, 'ip' rule represents ip address, 'user' rule " "represents username or usergroup, 'cephx' rule represents ceph auth ID, and " "'cert' rule represents certificate." msgstr "" "스냅샷에 정책 규칙을 추가합니다. 'ip' 규칙은 IP 주소를, 'user' 규칙은 사용자 " "이름이나 사용자 그룹을, 'cephx' 규칙은 ceph auth ID를, 'cert' 규칙은 인증서" "를 타나냅니다." msgid "Add rule" msgstr "규칙 추가" msgid "Add security services to share network." msgstr "공유 네트워크에 보안 서비스 추가." msgid "All keys and values must be in range from 1 to 255." msgstr "모든 키와 값은 1 에서 255까지의 범위에 있어야 합니다." msgid "All pairs that are in field for left are set for this metadata." msgstr "왼쪽 필드에 있는 모든 쌍은 이 메타데이터로 설정됩니다." msgid "All pairs that are in field for left are set for this share group type." msgstr "왼쪽 필드에 있는 모든 쌍이 공유 그룹 타입으로 설정됩니다." msgid "All pairs that are in field for left are set for this share type." msgstr "왼쪽 필드에 있는 모든 쌍은 공유 타입으로 설정됩니다." msgid "Allow project access to share group type." msgstr "프로젝트가 공유 그룹 유형에 액세스하도록 허용" msgid "Allow project access to share type." msgstr "프로젝트가 공유 유형에 엑세스하도록 허용합니다." msgid "At least one security service must be specified." msgstr "최소한 하나의 보안 서비스를 지정해야 합니다." msgid "At least one share type must be specified." msgstr "적어도 하나의 공유 유형이 지정되어야 합니다." msgid "Availability Zone" msgstr "가용 구역" msgid "Availability zone" msgstr "가용성 존" msgctxt "Current status of replica" msgid "Available" msgstr "사용 가능" msgctxt "Current status of share" msgid "Available" msgstr "사용 가능" msgctxt "Current status of snapshot" msgid "Available" msgstr "사용 가능" msgid "Available networks" msgstr "사용가능한 네트워크" msgid "Available projects" msgstr "사용 가능한 프로젝트" msgid "Available security services" msgstr "이용가능한 보안 서비스" msgid "Cancel" msgstr "취소" msgid "Cancel Migration" msgstr "마이그레이션 취소" msgid "Cancel migration" msgstr "마이그레이션 취소" msgid "Cancel migration of a Share" msgstr "공유에 대한 마이그레이션 취소" msgid "" "Cancel migration of a migrating share.

This is equivalent to the " "'manila migration-cancel' command." msgstr "" "마이그레이션 공유에서 마이그레이션을 취소합니다.

'manila " "migration-cancel' 명령과 동일합니다." msgid "Choose a snapshot" msgstr "스냅샷 선택" msgid "Complete Migration" msgstr "마이그레이션 완료" msgid "Complete migration" msgstr "마이그레이션 완료" msgid "Complete migration of a Share" msgstr "공유에 대한 마이그레이션 완료" msgid "" "Complete migration of a migrating share to another Manila host. This " "operation is expected to be disruptive.

This is equivalent to the " "'manila migration-complete' command." msgstr "" "다른 Manila 호스트로 마그레이션 중인 공유를 마이그레이션 완료로 변경합니다. " "이 작업은 서비스에 영향이 있을 수 있습니다.

'manila migration-" "complete' 명령과 동일합니다." msgid "Confirm Migration Cancelling of Share" msgstr "공유에 대한 마이그레이션 취소 확인" msgid "Confirm Migration Completion of Share" msgstr "공유에 대한 마이그레이션 완료 확인" msgid "Confirm Obtaining migration progress of Share" msgstr "공유에 대한 마이그레이션 진행사항을 가져오는 것에 대해 확인합니다" msgid "Confirm Password" msgstr "비밀번호 확인" msgid "Confirm Unmanage Share" msgstr "공유 관리 해제 확인" msgid "Create" msgstr "생성" msgid "Create Group Share Type" msgstr "공유 그룹 타입 생성" msgid "Create Replica" msgstr "레플리카 생성" msgid "Create Security Service" msgstr "보안 서비스 생성" msgid "Create Share" msgstr "공유 생성" msgid "Create Share Group" msgstr "공유 그룹 생성" msgid "Create Share Group Snapshot" msgstr "공유 그룹 스냅샷 생성" msgid "Create Share Group Type" msgstr "공유 그룹 타입 생성" msgid "Create Share Network" msgstr "공유 네트워크 생성" msgid "Create Share Replica" msgstr "공유 레플리카 생성" msgid "Create Share Snapshot" msgstr "공유 스냅샷 생성" msgid "Create Share Type" msgstr "공유 유형 생성" msgid "Create a Share" msgstr "공유 생성" msgid "Create share replica in specific availability zone." msgstr "특정 가용 구역 내 공유 레플리카 생성" msgid "Created" msgstr "생성됨" msgid "Created At" msgstr "생성 시점" msgid "Created at" msgstr "생성 시점" msgctxt "Current status of replica" msgid "Creating" msgstr "생성 중" msgctxt "Current status of share" msgid "Creating" msgstr "생성 중" msgctxt "Current status of share server" msgid "Creating" msgstr "생성 중" msgctxt "Current status of snapshot" msgid "Creating" msgstr "생성 중" #, python-format msgid "Creating replica for share \"%s\"." msgstr "공유 \"%s\"를 위한 레플리카를 생성하는 중. " #, python-format msgid "Creating rule for \"%s\"" msgstr "\"%s\"를 위한 생성 규칙" #, python-format msgid "Creating share \"%s\"" msgstr "공유 \"%s\"를 생성하는중" #, python-format msgid "Creating share group \"%s\"" msgstr "공유 그룹 \"%s\" 생성" #, python-format msgid "Creating share group snapshot \"%s\"." msgstr "공유 그룹 스냅샷 \"%s\" 생성." #, python-format msgid "Creating share snapshot \"%s\"." msgstr "공유 스냅샷 \"%s\" 생성" #, python-format msgid "Creating snapshot rule for \"%s\"" msgstr "\"%s\"의 스냅샷 규칙 생성 중" msgid "Current Size (GiB)" msgstr "현재 크기 (GiB)" msgid "DNS IP" msgstr "DNS IP" msgid "Delete Replica" msgid_plural "Delete Replicas" msgstr[0] "레플리카 삭제" msgid "Delete Rule" msgid_plural "Delete Rules" msgstr[0] "규칙 삭제" msgid "Delete Security Service" msgid_plural "Delete Security Services" msgstr[0] "보안 서비스 삭제" msgid "Delete Share" msgid_plural "Delete Shares" msgstr[0] "공유 삭제" msgid "Delete Share Group" msgid_plural "Delete Share Groups" msgstr[0] "공유 그룹 삭제" msgid "Delete Share Group Snapshot" msgid_plural "Delete Share Group Snapshots" msgstr[0] "공유 그룹 스냅샷 삭제" msgid "Delete Share Group Type" msgid_plural "Delete Share Group Types" msgstr[0] "공유 그룹 유형 삭제" msgid "Delete Share Network" msgid_plural "Delete Share Networks" msgstr[0] "공유 네트워크 삭제" msgid "Delete Share Server" msgid_plural "Delete Share Server" msgstr[0] "공유 서버 삭제" msgid "Delete Share Snapshot" msgid_plural "Delete Share Snapshots" msgstr[0] "공유 스냅샷 삭제" msgid "Delete Share Snapshot Rule" msgid_plural "Delete Share Snapshot Rules" msgstr[0] "공유 스냅샷 규칙 삭제" msgid "Delete Share Type" msgid_plural "Delete Share Types" msgstr[0] "공유 유형 삭제" msgid "Delete Snapshot" msgid_plural "Delete Snapshots" msgstr[0] "스냅샷 삭제" msgid "Deleted Replica" msgid_plural "Deleted Replicas" msgstr[0] "레플리카 삭제됨" msgid "Deleted Rule" msgid_plural "Deleted Rules" msgstr[0] "규칙 삭제됨" msgid "Deleted Security Service" msgid_plural "Deleted Security Services" msgstr[0] "보안 서비스 삭제됨" msgid "Deleted Share" msgid_plural "Deleted Shares" msgstr[0] "삭제된 공유" msgid "Deleted Share Group" msgid_plural "Deleted Share Groups" msgstr[0] "공유 그룹 삭제됨" msgid "Deleted Share Group Snapshot" msgid_plural "Deleted Share Group Snapshots" msgstr[0] "공유 그룹 스냅샷 삭제됨" msgid "Deleted Share Group Type" msgid_plural "Deleted Share Group Types" msgstr[0] "공유 그룹 유형이 삭제됨" msgid "Deleted Share Network" msgid_plural "Deleted Share Networks" msgstr[0] "삭제된 공유 네트워크" msgid "Deleted Share Server" msgid_plural "Deleted Share Server" msgstr[0] "삭제된 공유 서버" msgid "Deleted Share Snapshot" msgid_plural "Deleted Share Snapshots" msgstr[0] "삭제된 공유 스냅샷" msgid "Deleted Share Snapshot Rule" msgid_plural "Deleted Share Snapshot Rules" msgstr[0] "삭제된 공유 스냅샷 규칙" msgid "Deleted Share Type" msgid_plural "Deleted Share Types" msgstr[0] "삭제된 공유 유형" msgid "Deleted Snapshot" msgid_plural "Deleted Snapshots" msgstr[0] "삭제된 스냅샷" msgctxt "Current status of replica" msgid "Deleting" msgstr "Deleting" msgctxt "Current status of share" msgid "Deleting" msgstr "삭제 중" msgid "Description" msgstr "설명" msgid "Description:" msgstr "설명:" msgid "Destination host and pool where share will be migrated to." msgstr "공유가 마이그레이션 될 대상 호스트와 풀." msgid "Domain" msgstr "도메인" msgid "Driver handles share servers" msgstr "드라이버는 공유 서버를 다룹니다" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "드라이버 옵션 (Generic 드라이브에 대한 'volume_id' 등)" #, python-format msgid "Duplicated keys '%s'." msgstr "중복된 키 '%s'." msgid "Edit" msgstr "편집" msgid "Edit Security Service" msgstr "보안 서비스 편집" msgid "Edit Share" msgstr "공유편집" msgid "Edit Share Metadata" msgstr "공유 메타데이터 편집" msgid "Edit Share Network" msgstr "공유 네트워크 편집" msgid "Edit Share Snapshot" msgstr "공유 스냅샷 편집" msgid "Edit Share network" msgstr "공유 네트워크 편집" msgid "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgstr "" "목적지로 공유 스냅샷의 마이그레이션을 강제합니다. True일 경우 호스트 지원 마" "이그레이션을 시도하지 않습니다." msgid "" "Enforces migration to be nondisruptive. If set to True, host-assisted " "migration will not be attempted." msgstr "" "마이그레이션을 무중단이 되도록 강제. True일 경우 호스트 지원 마이그레이션을 " "시도하지 않습니다." msgid "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgstr "" "컨텐츠가 옮겨지는 도중 공유의 쓰기 가능을 유지하도록 마이그레이션을 강제합니" "다. True일 경우 호스트 지원 마이그레이션을 시도하지 않습니다." msgid "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgstr "" "컨텐츠를 옮길 때 모든 파일을 보존하기 위해 마이그레이션을 강제합니다. True일 " "경우 호스트 지원 마이그레이션을 시도하지 않습니다." msgid "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimizations." msgstr "호스트 지원 마이그레이션 방식의 사용을 강제합니다." msgctxt "Current status of replica" msgid "Error" msgstr "에러" msgctxt "Current status of share" msgid "Error" msgstr "에러" msgctxt "Current status of share network" msgid "Error" msgstr "에러" msgctxt "Current status of share server" msgid "Error" msgstr "오류" msgctxt "Current status of snapshot" msgid "Error" msgstr "오류" msgid "Expected only pairs of key=value." msgstr "key=value 쌍만을 기대합니다." msgid "Export location" msgstr "위치 내보내기" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "공유에 대한 내보내기 위치. NFS 예시: 1.2.3.4:/path/to/share" msgid "Export locations" msgstr "위치 내보내기" msgctxt "Current status of share" msgid "Extending Error" msgstr "확장중 에러" msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "부가 스펙 'driver_handles_share_servers'가 필요하고 불리언 값이 있어야 합니" "다." msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "부가 스펙 'driver_handles_share_servers'가 필요하고 불리언 값이 있어야 합니" "다." msgid "Extra specs" msgstr "부가 스펙" msgid "Force Host Assisted Migration" msgstr "호스트 지원 마이그레이션 강제" msgid "From here you can modify name and description of a security service." msgstr "여기서 보안 서비스의 이름과 설명을 수정할 수 있습니다." msgid "" "From here you can modify name and description of a share group snapshot." msgstr "여기서 공유 그룹 스냅샷의 이름과 설명을 수정할 수 있습니다." msgid "From here you can modify name and description of a share network." msgstr "여기서 공유 네트워크의 이름과 설명을 수정할 수 있습니다." msgid "From here you can modify name and description of a snapshot." msgstr "여기서 스냅샷의 이름과 설명을 수정할 수 있습니다." msgid "" "From here you can modify name, description and visibility of a share group." msgstr "여기서 공유 그룹의 이름, 설명, 표시 여부를 수정할 수 있습니다." msgid "From here you can modify name, description and visibility of a share." msgstr "여기서 공유의 이름, 설명, 표시 여부를 수정할 수 있습니다." msgid "From here you can revert the share to its latest snapshot." msgstr "여기서 가장 최근의 스냅샷으로 공유를 되돌릴 수 있습니다." msgid "From here you can update share network info. " msgstr "여기서 공유 네트워크 정보를 업데이트 할 수 있습니다." msgid "From here you can update the default share quotas (max limits)." msgstr "여기서 기본 공유 quotas (최대 한도)를 업데이트 할 수 있습니다." msgid "Get Migration Progress" msgstr "마이그레이션 진행사항 가져오기" msgid "Get migration progress" msgstr "마이그레이션 진행사항 가져오기" msgid "GiB" msgstr "GiB" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "'driver_options' 필드에 대해 적절하지 않은 값을 얻었습니다. key=value 쌍만을 " "기대합니다." msgid "Group specs" msgstr "그룹 사양" msgid "Here can be modified extra-specs for share type." msgstr "여기서 공유 타입에 대한 부가 스펙을 수정할 수 있습니다." msgid "Here can be modified group-specs for share group type." msgstr "여기서 공유 그룹 타입에 대한 그룹 스펙을 수정할 수 있습니다." msgid "Host" msgstr "호스트" msgid "Host of share" msgstr "공유 호스트" msgid "Host to migrate share" msgstr "공유를 마이그레이션할 호스트" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "공유가 위치할 호스트, 예시: some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "IP 버전" msgid "Id" msgstr "Id" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "필요한 부가 스펙 'spec_driver_handles_share_servers' 을 설정하는 데 적절하지 " "않은 값입니다. 허용 값은 %s 로 대소문자를 구별하지 않습니다." msgctxt "Current status of share server" msgid "In-use" msgstr "사용 중" msgctxt "Current status of snapshot" msgid "In-use" msgstr "사용 중" msgctxt "Current status of share network" msgid "Inactive" msgstr "비활성화 됨" #, python-format msgid "Key '%s' has improper length." msgstr "키 '%s' 길이가 적절하지 않습니다." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "키는 공백을 포함할 수 없습니다. 문자열 '%s' 를 살펴 봅니다." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "키는 공백을 포함하지 않아야 합니다. '%s' 에 오류가 있습니다." msgid "Limit" msgstr "제한" msgid "Manage" msgstr "관리" msgctxt "Current status of share" msgid "Manage Error" msgstr "관리 오류" msgid "Manage Replicas" msgstr "레플리카 관리" msgid "Manage Rules" msgstr "관리 규칙" msgid "Manage Share" msgstr "공유 관리" msgid "Manage Share Group Type Access" msgstr "공유 그룹 유형 액세스 관리" msgid "Manage Share Snapshot Rules" msgstr "공유 스냅샷 규칙 관리" msgid "Manage Share Type Access" msgstr "공유 유형 액세스 관리" msgid "Metadata" msgstr "메타데이터" msgid "Migrate Share" msgstr "공유 마이그레이션" msgid "Migrate a Share" msgstr "공유 마이그레이션" msgid "" "Migrate an existing share to another Manila host. This will move all your " "share data from one host to another.

This is equivalent to the " "'manila migration-start' command." msgstr "" "기존 공유를 다른 Manila 호스트로 마이그레이션 합니다. 이렇게하면 모든 공유 데" "이터가 명령을 실행한 호스트에서 다른 호스트로 이동합니다.

" "'manila migration-start' 명령과 동일합니다." msgctxt "Current status of share" msgid "Migrating" msgstr "이전 중" msgctxt "Current status of share" msgid "Migrating to" msgstr "로 이전 중" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "공유 %(name)s 에 대한 마이그레이션이 현재 %(progress)s 퍼센트입니다." msgid "Mount snapshot support" msgstr "스냅샷 마운트 지원" msgid "Name" msgstr "이름" msgid "Net Details" msgstr "네트워크 상세 정보" msgid "Network" msgstr "네트워크" msgid "Network Type" msgstr "네트워크 유형" msgid "Networks" msgstr "네트워크" msgid "Neutron Net" msgstr "Neutron Net" msgid "Neutron Subnet" msgstr "Neutron 서브넷" msgid "New Size (GiB)" msgstr "새 크기 (GiB)" msgid "New share network to be set in migrated share" msgstr "마이그레이션된 공유에서 설정될 새로운 공유 네트워크" msgid "New share type to be set in migrating share" msgstr "마이그레이션된 공유에서 설정될 새로운 공유 네트워크 타입" msgid "No projects found." msgstr "프로젝트를 찾을 수 없습니다." msgid "No projects selected." msgstr "선택한 프로젝트가 없습니다." msgid "No security services found." msgstr "보안 서비스를 찾을 수 없습니다." msgid "No security services selected." msgstr "보안 서비스가 선택되지 않았습니다." msgid "No source, empty share" msgstr "소스가 없음, 빈 공유" msgid "No source, empty share group" msgstr "소스가 없음, 빈 공유 그룹" msgid "Nondisruptive" msgstr "무중단" msgid "Number of Share Snapshots" msgstr "공유 스냅샷 갯수" msgid "Number of Shares" msgstr "공유 갯수" msgid "Obtain Progress" msgstr "진행사항 가져오기" msgid "Obtain migration progress of a Share" msgstr "공유에 대한 마이그레이션 진행사항 가져오기" msgid "" "Obtains migration progress of a migrating share.

This is " "equivalent to the 'manila migration-get-progress' command." msgstr "" "마이그레이션 중인 공유에 대한 진행률을 얻습니다.

'malila " "migration-get-progress' 명령과 동일합니다." msgid "One line - one action. Empty strings will be ignored." msgstr "One line - 하나의 동작. 빈 문자열은 무시됩니다." msgid "Overview" msgstr "개요" msgid "Password" msgstr "암호" msgid "Passwords do not match." msgstr "비밀번호가 일치하지 않습니다." msgid "Placeholder for description of share group type access managing form." msgstr "공유 그룹 타입 접근 관리 양식에 대한 설명을 위한 자리 표시자입니다." msgid "Placeholder for description of share type access managing form." msgstr "굥유 타입 접근 관리 양식에 대한 설명을 위한 자리 표시자입니다." msgid "Preserve Metadata" msgstr "메타데이터 보존" msgid "Preserve Snapshots" msgstr "스냅샷 보존" msgid "Project" msgstr "프로젝트" msgid "Projects with access to share group type" msgstr "공유 그룹 유형에 대한 액세스를 포함하는 프로젝트" msgid "Projects with access to share type" msgstr "공유 유형에 대한 엑세스를 포함하는 프로젝트" msgid "Protocol" msgstr "프로토콜" msgid "Public" msgstr "공용" msgid "Quota Name" msgstr "Quota 이름" msgid "Replica Details" msgstr "레플리카 상세 정보" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "레플리카 상세정보: %(replica_display_name)s" msgid "Replica State" msgstr "레플리카 상태" msgid "Replica state" msgstr "레플리카 상태" msgid "Replicas" msgstr "레플리카" msgid "Reset Replica State" msgstr "레플리카 상태 리셋" msgid "Reset Replica Status" msgstr "레플리카 상태 리셋" msgid "Reset Share Group Snapshot Status" msgstr "공유 그룹 스냅샷 상태 재설정" msgid "Reset Share Group Status" msgstr "공유 그룹 상태 초기화" msgid "Reset Status" msgstr "상태 재설정" msgid "Reset replica state" msgstr "레플리카 상태 초기화" msgid "Reset replica status" msgstr "레플리카 상태 초기화" msgid "Reset share replica's state with ID" msgstr "ID와 공유 레플리카 상태를 초기화" msgid "Reset share replica's status with ID" msgstr "ID로 공유 레플리카 상태를 초기화" msgid "Reset state" msgstr "state 리셋" msgid "Reset status" msgstr "리셋 status" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "레플리카 ('%(id)s') 상태를 '%(from)s' 에서 '%(to)s' 로 초기화합니다." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "레플리카 ('%(id)s') 상태를 '%(from)s' 에서 '%(to)s' 로 초기화합니다." #, python-format msgid "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "공유 그룹 ('%(id)s') 상태를 '%(from)s' 에서 '%(to)s' 로 초기화." #, python-format msgid "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "공유 그룹 스냅샷 ('%(id)s') 상태를 '%(from)s' 에서 '%(to)s' 로 초기화." msgid "Resync" msgstr "재동기화" msgid "Resync Replica" msgstr "레플리카 재동기화" msgid "Resync replica" msgstr "레플리카 재동기화" msgid "Resync share replica with ID" msgstr "ID로 공유 레플리카 재동기화" #, python-format msgid "Resync'ing replica '%s'" msgstr "레플리카 '%s' 재동기화 중" msgid "Revert Share" msgstr "공유 되돌리기" msgid "Revert Share to a Snapshot" msgstr "공유를 스냅샷으로 되돌리기" msgid "Revert share to a snapshot" msgstr "공유를 스냅샷으로 되돌리기" msgctxt "Current status of share" msgid "Reverting Error" msgstr "되돌리기 에러" msgid "Rules" msgstr "규칙" msgid "Save Changes" msgstr "변경사항 저장" msgid "Security Service Details" msgstr "보안 서비스 상세 정보" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "보안 서비스 상세정보: %(service_display_name)s" msgid "Security Service Overview" msgstr "보안 서비스 개요" msgid "Security Services" msgstr "보안 서비스" msgid "Security services within share network" msgstr "공유 네트워크 내 보안 서비스 " msgid "Segmentation Id" msgstr "구분 Id" msgid "Select parameters of share group you want to create. " msgstr "만들고자 하는 공유 그룹의 매개변수를 선택하세요." msgid "Select parameters of share you want to create. " msgstr "만들고자 하는 공유의 매개변수를 선택하세요." msgid "Selected Networks" msgstr "선택된 네트워크" msgid "Selected Projects" msgstr "선택된 프로젝트" msgid "Selected projects" msgstr "선택한 프로젝트" msgid "Selected security services" msgstr "선택된 보안 서비스" msgid "Server" msgstr "서버" msgid "Set Replica as Active" msgstr "레플리카를 활성화 상태로 설정" msgid "Set as Active" msgstr "활성화 상태로 설정" msgid "Set maximum quotas for the project." msgstr "프로젝트에대한 최대 quota를 설정합니다." msgid "Set share replica with ID" msgstr "ID와 공유 리플리카 설정" #, python-format msgid "Setting replica \"%s\" as active..." msgstr "레플리카 \"%s\"를 활성화 상태로 설정" msgid "Share" msgstr "공유" #, python-format msgid "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgstr "성공적으로 공유 \"%(s)s\"는 스냅샷 \"%(ss)s\"으로 되돌려졌습니다." msgid "Share Details" msgstr "공유 상세 정보" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "공유 상세정보: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "공유 세부 사항: %(share_name)s" msgid "Share Group" msgstr "공유 그룹" msgid "Share Group Details" msgstr "공유 그룹 새부 정보" #, python-format msgid "Share Group Details: %s" msgstr "공유 그룹 상세 정보: %s" msgid "Share Group Name" msgstr "공유 그룹 이름" msgid "Share Group Overview" msgstr "공유 그룹 개요" msgid "Share Group Snapshot" msgstr "공유 그룹 스냅샷" msgid "Share Group Snapshot Details" msgstr "공유 그룹 스냅샷 상세 정보" #, python-format msgid "Share Group Snapshot Details: %(sgs_display_name)s" msgstr "공유 그룹 스냅샷 세부 사항: %(sgs_display_name)s" msgid "Share Group Snapshot Overview" msgstr "공유 그룹 스냅샷 개요" msgid "Share Group Snapshots" msgstr "공유 그룹 스냅샷" msgid "Share Group Type" msgstr "공유 그룹 유형" msgid "Share Group Types" msgstr "공유 그룹 타입" msgid "Share Groups" msgstr "공유 그룹" msgid "Share ID" msgstr "공유 ID" msgid "Share Instance Details" msgstr "공유 인스턴스 상세 정보" #, python-format msgid "Share Instance Details: %s" msgstr "공유 인스턴스 세부 사항: %s" msgid "Share Instance Overview" msgstr "공유 인스턴스 개요" msgid "Share Instances" msgstr "공유 인스턴스" msgid "Share Limits" msgstr "공유 제한" msgid "Share Name" msgstr "공유 이름" msgid "Share Network" msgstr "공유 네트워크" msgid "Share Network Details" msgstr "공유 네트워크 상세 정보" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "공유 네트워크 상세 정보: %(network_display_name)s" msgid "Share Network Info" msgstr "공유 네트워크 정보" msgid "Share Network Overview" msgstr "공유 네트워크 개요" msgid "Share Networks" msgstr "공유 네트워크" msgid "Share Overview" msgstr "공유 개요" msgid "Share Protocol" msgstr "공유 프로토콜" msgid "Share Quotas" msgstr "공유 Quotas" msgid "Share Replica Overview" msgstr "공유 레플리카 개요" msgid "Share Replicas" msgstr "공유 레플리카" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "공유 레플리카 : %(share_display_name)s" msgid "Share Rules" msgstr "공유 규칙" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "공유 규칙들: %(share_display_name)s" msgid "Share Server" msgstr "공유 서버" msgid "Share Server Details" msgstr "공유 서버 상세 정보" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "공유 서버 세부 사항: %(server_name)s" msgid "Share Server Id" msgstr "공유 서버 Id" msgid "Share Server Overview" msgstr "공유 서버 개요" msgid "Share Servers" msgstr "공유 서버" msgid "Share Snapshot Details" msgstr "공유 스냅샷 상세 정보" msgid "Share Snapshot Name" msgstr "공유 스냅샷 이름" msgid "Share Snapshot Overview" msgstr "공유 스냅샷 개요" msgid "Share Snapshot Rules" msgstr "공유 스냅샷 규칙" msgid "Share Snapshots" msgstr "공유 스냅샷" msgid "Share Snapshots Storage" msgstr "공유 스냅샷 저장소" msgid "" "Share Snapshots are used for storing share changes and creating shares. " msgstr "스냅샷 공유는 공유 변화내역 저장과 공유 생성에 사용됩니다." msgid "Share Source" msgstr "공유 소스" msgid "Share Storage" msgstr "공유 저장소" msgid "Share Type" msgstr "공유 유형" msgid "Share Types" msgstr "공유 유형" msgid "Share Types (multiple available)" msgstr "공유 유형 (복수 사용 가능)" msgid "Share Types (one available)" msgstr "공유 유형 (단일 사용 가능)" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "사용가능한 quota의 %(avail)iGiB에서 %(req)iGiB로 공유를 확장하지 못했습니다." msgid "Share gigabytes" msgstr "기가바이트 공유" msgid "Share name to be assigned" msgstr "할당될 공유 이름" msgid "Share network" msgstr "공유 네트워크" msgid "" "Share networks contain network data, that will be used for creation of " "service VM, where will be hosted shares." msgstr "" "공유 네트워크에는 공유 데이터가 있는 서비스 VM을 만드는데 사용되는 네트워크 " "데이터가 포함됩니다." #, python-format msgid "Share replica %s has been deleted." msgstr "공유 레플리카 %s 를 삭제하였습니다." msgid "Share server" msgstr "공유 서버" #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "공유 크기는 스냅샷 크기 (%sGiB)보다 크거나 같아야합니다." msgid "Share snapshot gigabytes" msgstr "스냅샷 기가바이트 공유" msgid "Share snapshots" msgstr "스냅샷 공유" msgid "Share type" msgstr "공유 유형" msgid "Share types" msgstr "공유 유형" msgid "Shared Quotas" msgstr "공유 Quota" msgid "Shares" msgstr "공유" msgid "Shares on this server" msgstr "서버 공유" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "크기" msgid "Size (GiB)" msgstr "크기 (GiB)" msgid "Snapshot" msgstr "스냅샷" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "스냅샷 상세정보: %(snapshot_display_name)s" msgid "Snapshot ID" msgstr "스냅샷 ID" msgid "Snapshot Overview" msgstr "스냅샷 개요" #, python-format msgid "Snapshot Rules: %(snapshot_display_name)s" msgstr "스냅샷 규칙: %(snapshot_display_name)s" msgid "Source" msgstr "소스" msgid "Source SG Snapshot" msgstr "소스 SG 스냅샷" msgid "Source Share Group" msgstr "공유 그룹 원본" msgid "Source Share Group Snapshot" msgstr "공유 그룹 스냅샷 소스" msgid "Source Type" msgstr "소스 유형" msgid "Source share group snapshot" msgstr "소스 공유 그룹 스냅샷" msgid "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgstr "" "공유에 사용될 새 공유 네트워크를 지정하세요. 만약 마이그레이션 공유가 현재 공" "유 네트워크 안에서 유지되어야 한다면 이 매개변수를 지정하면 안 됩니다." msgid "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgstr "" "공유를 위한 새로운 공유 유형을 지정하세요. 만약 마이그레이션 공유가 현재 공" "유 유형 내에서 유지되어야 한다면 이 매개변수를 지정하면 안 됩니다." msgid "Specs" msgstr "사양" msgid "Start migration" msgstr "마이그레이션 시작" msgid "Status" msgstr "상태" msgid "Submit" msgstr "제출" msgid "Subnet" msgstr "서브넷" #, python-format msgid "Successfully created security service: %s" msgstr "보안 서비스: %s 를 성공적으로 생성하였습니다" #, python-format msgid "Successfully created share group type: %s" msgstr "성공적으로 생성됨. 공유 그룹 타입: %s" #, python-format msgid "Successfully created share network: %s" msgstr "공유 네트워크: %s 를 성공적으로 생성하였습니다" #, python-format msgid "Successfully created share type: %s" msgstr "공유 유형: %s 를 성공적으로 생성하였습니다" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "공유 %s 에 대한 마이그레이션 취소 요청을 성공적으로 전송하였습니다." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "" "공유 %s 에 대한 마이그레이션을 완료하기 위해 요청을 성공적으로 전송하였습니" "다." #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "공유를 관리하기 위해 요청을 성공적으로 전송하였습니다: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "요청을 마이그레이션 공유에 성공적으로 보냈습니다: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "공유를 관리 해제하기 위해 요청을 성공적으로 전송하였습니다: %s" #, python-format msgid "Successfully updated group specs for share group type '%s'." msgstr "공유 그룹 타입 '%s'의 그룹 스펙을 성공적으로 갱신하였습니다." #, python-format msgid "Successfully updated security service \"%s\"" msgstr "시큐리티 서비스 %s를 성공적으로 업데이트 하였습니다." msgid "Task state" msgstr "작업 상태" msgid "" "The security service can be used by backend drivers to configure clients, " "for more secure using of share." msgstr "" "보안 서비스는 백엔드 드라이버를 통한 공유를 보다 더 안전하게 사용하기위해 클" "라이언트를 구성하는데 사용할 수 있습니다." msgid "" "The share group type defines the characteristics of a share group backend." msgstr "공유 그룹 타입은 공유 그룹 백엔드 특성을 정의합니다." #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "공유 크기는 스냅샷 크기 (%sGiB)보다 작을 수 없습니다." msgid "The share type defines the characteristics of a share backend." msgstr "공유 타입은 공유 백엔드에대한 특성을 정의합니다." msgid "To add extra-specs use:" msgstr "부가 스펙을 추가하기 위해 사용합니다:" msgid "To add group-specs use:" msgstr "그룹 스펙을 추가하려면 다음을 사용합니다:" msgid "To add metadata use:" msgstr "메타데이터를 추가하려면 사용합니다:" msgid "To unset extra-specs use:" msgstr "부가 스펙을 설정 해제하려면 다음을 사용합니다:" msgid "To unset group-specs use:" msgstr "그룹 스펙을 설정 해제하려면 다음을 사용합니다:" msgid "To unset metadata use:" msgstr "메타데이터를 설정 해제하려면 다음을 사용합니다:" msgid "Total Gibibytes" msgstr "총 Gibibytes" msgid "Type" msgstr "유형" msgid "Unable to add rule." msgstr "규칙을 추가할 수 없습니다." msgid "Unable to add snapshot rule." msgstr "스냅샷 규칙을 추가할 수 없음." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "현재 공유 %s 에 대한 마이그레이션 취소를 가져올 수 없습니다." #, python-format msgid "Unable to complete migration of share %s." msgstr "공유 %s 에 대한 마이그레이션을 완료할 수 없습니다." msgid "Unable to create security service." msgstr "보안 서비스를 생성할 수 없습니다." msgid "Unable to create share group snapshot." msgstr "공유 그룹 스냅샷을 생성할 수 없습니다." msgid "Unable to create share group type." msgstr "공유 그룹 유형을 생성할 수 없습니다." msgid "Unable to create share group." msgstr "공유 그룹을 생성할 수 없습니다." msgid "Unable to create share network." msgstr "공유 네트워크를 생성할 수 없습니다." msgid "Unable to create share replica." msgstr "공유 레플리카를 생성할 수 없습니다." msgid "Unable to create share snapshot." msgstr "공유스냅샷을 생성할 수 없습니다" msgid "Unable to create share type." msgstr "공유 유형을 생성할 수 없습니다." msgid "Unable to create share." msgstr "공유를 생성할 수 없습니다." #, python-format msgid "Unable to create share. %s" msgstr "공유 %s를 생성할 수 없습니다." #, python-format msgid "Unable to delete replica \"%s\"." msgstr "레플리카 \"%s\" 를 삭제할 수 없습니다." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "규칙 \"%s\" 를 삭제 할 수 없습니다." #, python-format msgid "Unable to delete share \"%s\". " msgstr "공유 %s를 제거할 수 없습니다. " #, python-format msgid "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." msgstr "" "공유 그룹 스냅샷 \"%s\"을 삭제할 수 없습니다. 하나 이상의 공유 그룹이 의존하" "고 있습니다." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "\"%s\" 스냅샷을 삭제할 수 없습니다. 하나 이상의 공유에 의존하고 있습니다." #, python-format msgid "Unable to delete snapshot rule \"%s\"." msgstr "스냅샷 규칙 \"%s\"를 삭제할 수 없습니다." msgid "Unable to get information about share group type access." msgstr "공유 그룹 유형 액세스에 관련된 정보를 얻을 수 없습니다." msgid "Unable to get information about share type access." msgstr "공유 유형 액세스에 관련된 정보를 가져올 수 없습니다." msgid "Unable to get list of projects." msgstr "프로젝트 목록을 가져올 수 없습니다." msgid "Unable to get manila default quota." msgstr "Manila 기본 quota 값을 찾을 수 없습니다." msgid "Unable to get the security services hosts" msgstr "보안 서비스 호스트를 가져올 수 없습니다." #, python-format msgid "Unable to get the specified share group '%s' for snapshot creation." msgstr "스냅샷 생성을 위한 지정된 공유 그룹 '%s' 를 얻을 수 없습니다." msgid "Unable to load the specified share group snapshot." msgstr "지정된 공유 그룹 스냅샷을 불러들일 수 없습니다." msgid "Unable to load the specified snapshot." msgstr "지정한 스냅샷을 불러올 수 없습니다." msgid "Unable to manage share" msgstr "공유를 관리할 수 없습니다" #, python-format msgid "Unable to migrate share %s." msgstr "공유 %s를 마이그레이션할 수 없습니다." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "현재 공유 %s 에 대한 마이그레이션 과정을 가져올 수 없습니다." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "레플리카 '%s' 상태를 초기화할 수 없습니다" #, python-format msgid "Unable to reset status of replica '%s'." msgstr "레플리카 '%s' 상태를 초기화할 수 없습니다." #, python-format msgid "Unable to reset status of share group '%s'." msgstr "공유 그룹 '%s' 상태를 초기화할 수 없습니다." #, python-format msgid "Unable to reset status of share group snapshot '%s'." msgstr "공유 그룹 스냅샷 '%s'의 상태를 초기화할 수 없습니다." #, python-format msgid "Unable to resync replica '%s'." msgstr "레플리카 '%s' 를 재동기화할 수 없습니다." msgid "Unable to retrieve default share quotas." msgstr "기본 공유 quotas 를 찾을 수 없습니다." msgid "Unable to retrieve list of projects." msgstr "프로젝트 목록을 가져올 수 없습니다." msgid "Unable to retrieve quotas." msgstr "쿼터(quota)를 찾을 수 없습니다." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "레플리카 '%s' 를 가져올 수 없습니다." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "보안 서비스 '%s'의 상세정보를 가져올 수 없습니다." msgid "Unable to retrieve security services" msgstr "보안 서비스를 가져올 수 없습니다" msgid "Unable to retrieve security_service." msgstr "security_service를 찾지 못했습니다." msgid "Unable to retrieve share details." msgstr "공유 세부 사항을 가져올 수 없습니다." #, python-format msgid "Unable to retrieve share group '%s'." msgstr "공유 그룹 '%s'를 가져올 수 없습니다." msgid "Unable to retrieve share group details." msgstr "공유 그룹 상세 정보를 가져올 수 없습니다." #, python-format msgid "Unable to retrieve share group snapshot '%s'." msgstr "공유 그룹 스냅샷 '%s'을 가져올 수 없습니다." msgid "Unable to retrieve share group snapshot details." msgstr "공유 그룹 스냅샷 세부 사항을 가져올 수 없습니다." msgid "Unable to retrieve share group snapshot list." msgstr "공유 그룹 스냅샷 목록을 가져올 수 없습니다." msgid "Unable to retrieve share group snapshot." msgstr "공유 그룹 스냅샷을 가져올 수 없습니다." msgid "Unable to retrieve share group snapshots." msgstr "공유 그룹 스냅샷을 가져올 수 없습니다." msgid "Unable to retrieve share group types." msgstr "공유 그룹 유형을 가져올 수 없습니다." msgid "Unable to retrieve share group." msgstr "공유 그룹을 가져올 수 없습니다." msgid "Unable to retrieve share groups." msgstr "공유 그룹 상태를 가져올 수 없습니다." msgid "Unable to retrieve share instance details." msgstr "공유 인스턴스 세부 사항을 가져올 수 없습니다." msgid "Unable to retrieve share instances." msgstr "공유 인스턴스를 가져올 수 없습니다." msgid "Unable to retrieve share limit information." msgstr "공유 최대 사용량 정보를 찾지 못 했습니다." msgid "Unable to retrieve share list." msgstr "공유 목록을 가져올 수 없습니다." msgid "Unable to retrieve share network details." msgstr "공유 네트워크 상세정보를 가져올 수 없습니다." msgid "Unable to retrieve share network." msgstr "공유네트워크를 가져올 수 없습니다." msgid "Unable to retrieve share networks" msgstr "공유 네트워크를 가져올 수 없습니다" msgid "Unable to retrieve share replicas." msgstr "공유 레플리카를 가져올 수 없습니다." msgid "Unable to retrieve share rules." msgstr "공유 규칙을 찾을 수 없습니다." msgid "Unable to retrieve share server details." msgstr "공유 서버 세부 사항을 가져올 수 없습니다." msgid "Unable to retrieve share servers" msgstr "공유 서버를 가져올 수 없습니다" msgid "Unable to retrieve share snapshot list." msgstr "공유 스냅샷 목록을 가져올 수 없습니다." msgid "Unable to retrieve share snapshot rules." msgstr "공유 스냅샷 규칙을 가져올 수 없습니다." msgid "Unable to retrieve share snapshot." msgstr "공유 스냅샷을 가져올 수 없습니다." msgid "Unable to retrieve share snapshots list." msgstr "공유 스냅샷 목록을 찾을 수 없습니다." msgid "Unable to retrieve share snapshots." msgstr "공유 스냅샷을 찾지 못했습니다." msgid "Unable to retrieve share types." msgstr "공유 유형을 가져올 수 없습니다." msgid "Unable to retrieve share." msgstr "공유를 찾을 수 없습니다." #, python-format msgid "Unable to retrieve share. %s" msgstr "공유 %s를 가져올 수 없습니다. " msgid "Unable to retrieve share_gruop_type." msgstr "공유 그룹 유형을 가져올 수 없습니다." msgid "Unable to retrieve share_type." msgstr "share_type 을 가져올 수 없습니다." msgid "Unable to retrieve snapshot details." msgstr "스냅샷 상세정보를 찾을 수 없습니다." msgid "Unable to retrieve snapshot." msgstr "스냅샷을 찾을 수 없습니다." msgid "Unable to retrieve volume details." msgstr "볼륨 세부 사항을 가져올 수 없습니다." msgid "Unable to revert share to the snapshot." msgstr "공유를 스냅샷으로 되돌릴 수 없습니다." #, python-format msgid "Unable to set replica '%s' as active." msgstr "레플리카 \"%s\"를 활성화 상태로 설정 할 수 없습니다. " msgid "Unable to unmanage share." msgstr "공유를 관리 해제할 수 없습니다." #, python-format msgid "Unable to update access for share group type \"%s\"." msgstr "공유 그룹 유형 \"%s\"에 대한 업데이트를 할 수 없습니다." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "공유 유형 \"%s\" 에 대한 액세스를 업데이트할 수 없습니다." msgid "Unable to update default quotas." msgstr "기본 할당량을 업데이트할 수 없습니다." msgid "Unable to update group_specs for share group type." msgstr "공유 그룹 유형의 그룹 스펙을 업데이트할 수 없습니다." msgid "Unable to update security service." msgstr "보안 서비스를 업데이트 할 수 없습니다." msgid "Unable to update share group snapshot." msgstr "공유 그룹 스냅샷을 업데이트할 수 없습니다." msgid "Unable to update share group type." msgstr "공유 그룹 유형을 업데이트할 수 없습니다." msgid "Unable to update share group." msgstr "공유 그룹을 업데이트할 수 없습니다." msgid "Unable to update share metadata." msgstr "공유 메타데이터를 업데이트할 수 없습니다." #, python-format msgid "Unable to update share network \"%s\"." msgstr "공유 네트워크 \"%s\"를 업데이트 할 수 없습니다." msgid "Unable to update share network." msgstr "공유 네트워크를 업데이트 할 수 없습니다." msgid "Unable to update share snapshot." msgstr "공유 스냅샷을 업데이트할 수 없습니다." msgid "Unable to update share type." msgstr "공유 유형을 업데이트할 수 없습니다." msgid "Unable to update share." msgstr "공유를 업데이트할 수 없습니다." msgid "Unknown" msgstr "알 수 없음" msgid "Unmanage" msgstr "관리 해제" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "관리되지 않은 에러" msgid "Unmanage Share" msgstr "공유 관리 해제" msgid "Update" msgstr "업데이트" msgid "Update Share Group" msgstr "공유 그룹 업데이트" msgid "Update Share Group Snapshot" msgstr "공유 그룹 스냅샷 업데이트" msgid "Update Share Group Type" msgstr "공유 그룹 유형 업데이트" msgid "Update Share Network" msgstr "공유 네트워크 업데이트" msgid "Update Share Snapshot" msgstr "공유 스냅샷 업데이트" msgid "Update Share Type" msgstr "공유 유형 업데이트" msgid "Update Share group Type" msgstr "공유 그룹 유형 업데이트" msgid "Update share network" msgstr "공유 네트워크 업데이트" msgid "Updated" msgstr "업데이트됨" msgid "Updated At" msgstr "업데이트" #, python-format msgid "Updated access for share group type \"%s\"." msgstr "공유 그룹 유형 \"%s\"에 대한 액세스가 업데이트 되었습니다." #, python-format msgid "Updated access for share type \"%s\"." msgstr "공유 유형 \"%s\" 에 대한 엑세스를 업데이트하였습니다." #, python-format msgid "Updated share network \"%s\"." msgstr "공유 네트워크 \"%s\" 업데이트됨." #, python-format msgid "Updating share \"%s\"" msgstr "공유 \"%s\" 업데이트 중" #, python-format msgid "Updating share group \"%s\"" msgstr "공유 그룹 \"%s\" 업데이트 중" #, python-format msgid "Updating share group snapshot \"%s\"" msgstr "공유 그룹 스냅샷 \"%s\" 업데이트 중" #, python-format msgid "Updating share metadata \"%s\"" msgstr "공유 메타데이터 \"%s\" 업데이트중" #, python-format msgid "Updating share network \"%s\"" msgstr "공유 네트워크 \"%s\" 업데이트 중." #, python-format msgid "Updating share snapshot \"%s\"" msgstr "공유 스냅샷 \"%s\" 업데이트 중" msgid "Use share group snapshot as a source" msgstr "공유 그룹 스냅샷을 소스로 사용" msgid "Use snapshot as a source" msgstr "소스로 스냅샷 사용" msgid "User" msgstr "사용자" msgid "Visibility" msgstr "가시성" msgid "" "When a share is \"unmanaged\", the share will no longer be visible within " "OpenStack. Note that the share will not be deleted.

This is " "equivalent to the 'manila unmanage' command." msgstr "" "공유가 \"관리되지 않음\"으로 된 경우, 더이상 OpenStack에서 확인할 수 없습니" "다. 공유는 삭제되지 않습니다.

'manila unmanage' 명령과 동" "일합니다." msgid "Writable" msgstr "쓰기가능" msgid "as Active?" msgstr "활성화로?" msgid "key=value pairs per line can be set" msgstr "한 행 당 key=value 쌍을 설정 가능합니다" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/pt_BR/0000775000175000017500000000000000000000000017673 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/pt_BR/LC_MESSAGES/0000775000175000017500000000000000000000000021460 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/pt_BR/LC_MESSAGES/django.po0000664000175000017500000014337500000000000023277 0ustar00zuulzuul00000000000000# José Mello , 2016. #zanata # Fernando Pimenta , 2018. #zanata # Rodrigo Loures , 2018. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2018-04-24 07:33+0000\n" "Last-Translator: Fernando Pimenta \n" "Language-Team: Portuguese (Brazil)\n" "Language: pt_BR\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #, python-format msgid "%(used)s of %(quota)s GiB Used" msgstr "%(used)s de %(quota)s GiB Utilizado" #, python-format msgid "%(used)s of %(quota)s Used" msgstr "%(used)s de %(quota)s Utilizado" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(Cota excedida)" msgid "Access Key" msgstr "Chave de Acesso" msgid "Access Level" msgstr "Nível de Acesso" msgid "Access Rules" msgstr "Regras de Acesso" msgid "Access To" msgstr "Accesso Para" msgid "Access Type" msgstr "Tipo de Acesso" msgid "Access to" msgstr "Accesso para" msgctxt "Current status of share network" msgid "Active" msgstr "Ativo" msgctxt "Current status of share server" msgid "Active" msgstr "Ativo" msgid "Add" msgstr "Adicionar" msgid "Add Rule" msgstr "Adicionar Regra" msgid "Add Security Service" msgstr "Adicionar Serviço de segurança" msgid "Add Share Snapshot Rule" msgstr "Adicionar Regra de Snapshot de Compartilhamento" msgid "Add rule" msgstr "Adicionar regra" msgid "Add security services to share network." msgstr "Adicionar serviços de segurança à rede de compartilhamento." msgid "All keys and values must be in range from 1 to 255." msgstr "Todas as chaves e valores devem estar no intervalo de 1 a 255" msgid "All pairs that are in field for left are set for this metadata." msgstr "" "Todos os pares que estão no campo à esquerda estão definidos para este tipo " "de metadado." msgid "All pairs that are in field for left are set for this share group type." msgstr "" "Todos os pares que estão no campo à esquerda estão definidos para este tipo " "de grupo de compartilhamento." msgid "All pairs that are in field for left are set for this share type." msgstr "" "Todos os pares que estão no campo à esquerda estão definidos para este tipo " "de compartilhamento." msgid "Allow project access to share group type." msgstr "Permite ao projeto acessar tipo de grupo de compartilhamento." msgid "Allow project access to share type." msgstr "Permitir ao projeto acesso ao tipo de compartilhamento." msgid "At least one security service must be specified." msgstr "Pelo menos um serviço de segurança deve ser especificado." msgid "At least one share type must be specified." msgstr "Pelo menos um tipo de compartilhamento deve ser especificado." msgid "Availability Zone" msgstr "Zona de Disponibilidade" msgid "Availability zone" msgstr "Zona de disponibilidade" msgctxt "Current status of replica" msgid "Available" msgstr "Disponível" msgctxt "Current status of share" msgid "Available" msgstr "Disponível" msgctxt "Current status of snapshot" msgid "Available" msgstr "Disponível" msgid "Available networks" msgstr "Redes disponíveis" msgid "Available projects" msgstr "Projetos disponíveis" msgid "Available security services" msgstr "Serviços de segurança disponíveis" msgid "Cancel" msgstr "Cancelar" msgid "Cancel Migration" msgstr "Cancelar Migração" msgid "Cancel migration" msgstr "Cancelar Migração" msgid "Cancel migration of a Share" msgstr "Cancelar migração de um Compartilhamento" msgid "Choose a snapshot" msgstr "Escolher um snapshot" msgid "Complete Migration" msgstr "Completar Migração" msgid "Complete migration" msgstr "Completar Migração" msgid "Complete migration of a Share" msgstr "Completar migração de um Compartilhamento" msgid "Confirm Migration Cancelling of Share" msgstr "Confirmar o Cancelamento da Migração do Compartilhamento" msgid "Confirm Migration Completion of Share" msgstr "Confirmar o Término da Migração do Compartilhamento" msgid "Confirm Obtaining migration progress of Share" msgstr "Confirmar a Obtenção do progresso da migração do compartilhamento" msgid "Confirm Password" msgstr "Confirmar Senha" msgid "Confirm Unmanage Share" msgstr "Confirmar Remoção de Gerenciamento de Compartilhamento" msgid "Create" msgstr "Criar" msgid "Create Group Share Type" msgstr "Criar Tipo de Grupo de Compartilhamento." msgid "Create Replica" msgstr "Criar Réplica" msgid "Create Security Service" msgstr "Criar Serviço de segurança" msgid "Create Share" msgstr "Criar Compartilhamento" msgid "Create Share Group" msgstr "Criar Grupo de Compartilhamento" msgid "Create Share Group Snapshot" msgstr "Criar Snapshot do Grupo de Compartilhamento" msgid "Create Share Group Type" msgstr "Criar Tipo de Grupo de Compartilhamento" msgid "Create Share Network" msgstr "Criar Rede de Compartilhamento" msgid "Create Share Replica" msgstr "Criar Réplica de Compartilhamento" msgid "Create Share Snapshot" msgstr "Criar Snapshot do Compartilhamento" msgid "Create Share Type" msgstr "Criar Tipo de Compartilhamento" msgid "Create a Share" msgstr "Criar um Compartilhamento" msgid "Create share replica in specific availability zone." msgstr "" "Criar réplica de compartilhamento na zona de disponibilidade especificada." msgid "Created" msgstr "Criado" msgid "Created At" msgstr "Criado Em" msgid "Created at" msgstr "Criado em" msgctxt "Current status of replica" msgid "Creating" msgstr "Criando" msgctxt "Current status of share" msgid "Creating" msgstr "Criando" msgctxt "Current status of share server" msgid "Creating" msgstr "Criando" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Criando" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Criando réplica para compartilhamento \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Criando regra para \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Criando compartilhamento \"%s\"" #, python-format msgid "Creating share group \"%s\"" msgstr "Criando grupo de compartilhamento \"%s\"" #, python-format msgid "Creating share group snapshot \"%s\"." msgstr "Criando snapshot de grupo de compartilhamento \"%s\"." #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Criando snapshot do compartilhamento \"%s\"." #, python-format msgid "Creating snapshot rule for \"%s\"" msgstr "Criando regra de snapshot para \"%s\"" msgid "Current Size (GiB)" msgstr "Tamanho Atual (GiB)" msgid "DNS IP" msgstr "IP DNS" msgid "Delete Replica" msgid_plural "Delete Replicas" msgstr[0] "Excluir Réplica" msgstr[1] "Excluir Réplicas" msgid "Delete Rule" msgid_plural "Delete Rules" msgstr[0] "Excluir Regra" msgstr[1] "Excluir Regras" msgid "Delete Security Service" msgid_plural "Delete Security Services" msgstr[0] "Excluir Serviço de Segurança" msgstr[1] "Excluir Serviços de Segurança" msgid "Delete Share" msgid_plural "Delete Shares" msgstr[0] "Excluir Compartilhamento" msgstr[1] "Excluir Compartilhamentos" msgid "Delete Share Group" msgid_plural "Delete Share Groups" msgstr[0] "Excluir Grupo de Compartilhamento" msgstr[1] "Excluir Grupos de Compartilhamento" msgid "Delete Share Group Snapshot" msgid_plural "Delete Share Group Snapshots" msgstr[0] "Excluir Snapshot de Grupo de Compartilhamento" msgstr[1] "Excluir Snapshots de Grupo de Compartilhamento" msgid "Delete Share Group Type" msgid_plural "Delete Share Group Types" msgstr[0] "Excluir Tipo de Grupo de Compartilhamento" msgstr[1] "Excluir Tipos de Grupo de Compartilhamento" msgid "Delete Share Network" msgid_plural "Delete Share Networks" msgstr[0] "Excluir Rede de Compartilhamento" msgstr[1] "Excluir Redes de Compartilhamento" msgid "Delete Share Server" msgid_plural "Delete Share Server" msgstr[0] "Excluir Servidor de Compartilhamento" msgstr[1] " Excluir Servidor de Compartilhamento" msgid "Delete Share Snapshot" msgid_plural "Delete Share Snapshots" msgstr[0] "Excluir Snapshot de Compartilhamento" msgstr[1] "Excluir Snapshots de Compartilhamento" msgid "Delete Share Snapshot Rule" msgid_plural "Delete Share Snapshot Rules" msgstr[0] "Excluir Regra de Snapshot de Compartilhamento" msgstr[1] "Excluir Regras de Snapshot de Compartilhamento" msgid "Delete Share Type" msgid_plural "Delete Share Types" msgstr[0] "Excluir Tipo de Compartilhamento" msgstr[1] "Excluir Tipos de Compartilhamento" msgid "Delete Snapshot" msgid_plural "Delete Snapshots" msgstr[0] "Excluir Snapshot" msgstr[1] "Excluir Snapshots" msgid "Deleted Replica" msgid_plural "Deleted Replicas" msgstr[0] "Réplica Excluída" msgstr[1] "Réplicas Excluídas" msgid "Deleted Rule" msgid_plural "Deleted Rules" msgstr[0] "Regra Excluída" msgstr[1] "Regras Excluídas" msgid "Deleted Security Service" msgid_plural "Deleted Security Services" msgstr[0] "Serviço de Segurança Excluído" msgstr[1] "Serviços de Segurança Excluídos" msgid "Deleted Share" msgid_plural "Deleted Shares" msgstr[0] "Compartilhamento Excluído" msgstr[1] "Compartilhamentos Excluídos" msgid "Deleted Share Group" msgid_plural "Deleted Share Groups" msgstr[0] "Grupo de Compartilhamento Excluído" msgstr[1] "Grupos de Compartilhamento Excluídos" msgid "Deleted Share Group Snapshot" msgid_plural "Deleted Share Group Snapshots" msgstr[0] "Snapshot de Grupo de Compartilhamento Excluído" msgstr[1] "Snapshots de Grupo de Compartilhamento Excluídos" msgid "Deleted Share Group Type" msgid_plural "Deleted Share Group Types" msgstr[0] "Tipo de Grupo de Compartilhamento Excluído" msgstr[1] "Tipos de Grupo de Compartilhamento Excluídos" msgid "Deleted Share Network" msgid_plural "Deleted Share Networks" msgstr[0] "Rede de Compartilhamento Excluída" msgstr[1] "Redes de Compartilhamento Excluídas" msgid "Deleted Share Server" msgid_plural "Deleted Share Server" msgstr[0] " Servidor de Compartilhamento Excluído" msgstr[1] " Servidor de Compartilhamento Excluído" msgid "Deleted Share Snapshot" msgid_plural "Deleted Share Snapshots" msgstr[0] "Snapshot de Compartilhamento Excluído" msgstr[1] "Snapshots de Compartilhamento Excluídos" msgid "Deleted Share Snapshot Rule" msgid_plural "Deleted Share Snapshot Rules" msgstr[0] "Regra de Snapshot de Compartilhamento Excluída" msgstr[1] "Regras de Snapshot de Compartilhamento Excluídas" msgid "Deleted Share Type" msgid_plural "Deleted Share Types" msgstr[0] "Tipo de Compartilhamento Excluído" msgstr[1] "Tipos de Compartilhamento Excluídos" msgid "Deleted Snapshot" msgid_plural "Deleted Snapshots" msgstr[0] "Snapshot Excluído" msgstr[1] "Snapshots Excluídos" msgctxt "Current status of replica" msgid "Deleting" msgstr "Excluindo" msgctxt "Current status of share" msgid "Deleting" msgstr "Excluindo" msgid "Description" msgstr "Descrição" msgid "Description:" msgstr "Descrição:" msgid "Destination host and pool where share will be migrated to." msgstr "Host de destino e pool para onde o compartilhamento será migrado." msgid "Domain" msgstr "Domínio" msgid "Driver handles share servers" msgstr "Driver gerencia servidores de compartilhamento" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Opções do driver ('volume_id' para driver genérico, etc...)" #, python-format msgid "Duplicated keys '%s'." msgstr "Chaves duplicadas '%s'." msgid "Edit" msgstr "Editar" msgid "Edit Security Service" msgstr "Editar Serviço de segurança" msgid "Edit Share" msgstr "Editar Compartilhamento" msgid "Edit Share Metadata" msgstr "Editar Metadados do Compartilhamento" msgid "Edit Share Network" msgstr "Editar Rede de Compartilhamento" msgid "Edit Share Snapshot" msgstr "Editar Snapshot de Compartilhamento" msgid "Edit Share network" msgstr "Editar Rede de Compartilhamento" msgid "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgstr "" "Força a migração dos snapshots de compartilhamento para o destino. Se " "definido para True, a migração host-assisted não será tentada." msgid "" "Enforces migration to be nondisruptive. If set to True, host-assisted " "migration will not be attempted." msgstr "" "Força a migração a não ser disruptiva. Se definido para True, a migração " "host-assisted não será tentada." msgid "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgstr "" "Força a migração a manter o compartilhamento gravável enquanto o conteúdo " "estiver sendo movido. Se definido para True, a migração host-assisted não " "será tentada." msgid "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgstr "" "Força a migração a preservar todo o metadado de arquivo enquanto move seu " "conteúdo. Se definido para True a migração host-assisted não sera tentada." msgid "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimizations." msgstr "" "Força a utilização da abordagem host-assisted, que ignora otimizações do " "driver." msgctxt "Current status of replica" msgid "Error" msgstr "Erro" msgctxt "Current status of share" msgid "Error" msgstr "Erro" msgctxt "Current status of share network" msgid "Error" msgstr "Erro" msgctxt "Current status of share server" msgid "Error" msgstr "Erro" msgctxt "Current status of snapshot" msgid "Error" msgstr "Erro" msgid "Expected only pairs of key=value." msgstr "Esperados apenas pares de chave=valor." msgid "Export location" msgstr "Localização do Export" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "" "Exportar o local do compartilhamento. Exemplo para NFS:1.2.3.4:/caminho/para/" "compartilhamento" msgid "Export locations" msgstr "Exportar localizações" msgctxt "Current status of share" msgid "Extending Error" msgstr "Erro estendendo" msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "A especificação extra 'driver_handles_share_servers' é necessária e deve ter " "um valor booleano." msgid "" "Extra spec 'driver_handles_share_servers' is required and should have " "boolean value." msgstr "" "A especificação extra 'driver_handles_share_servers' é necessária e deve ter " "um valor booleano." msgid "Extra specs" msgstr "Especificações extras" msgid "Force Host Assisted Migration" msgstr "Forçar Migração Assistida do Host" msgid "From here you can modify name and description of a security service." msgstr "Aqui você modificar o nome e a descrição de um serviço de segurança." msgid "" "From here you can modify name and description of a share group snapshot." msgstr "" "Aqui você pode modificar o nome e a descrição de um snapshot de grupo de " "compartilhamento." msgid "From here you can modify name and description of a share network." msgstr "" "Aqui você pode modificar o nome e a descrição de uma rede de " "compartilhamento." msgid "From here you can modify name and description of a snapshot." msgstr "Aqui você pode modificar o nome e a descrição de um snapshot." msgid "" "From here you can modify name, description and visibility of a share group." msgstr "" "Aqui você pode modificar o nome, a descrição e a visibilidade de um grupo de " "compartilhamento." msgid "From here you can modify name, description and visibility of a share." msgstr "" "Aqui você pode modificar o nome, a descrição e a visibilidade do " "compartilhamento." msgid "From here you can revert the share to its latest snapshot." msgstr "Aqui você pode reverter o compartilhamento para o seu último snapshot." msgid "From here you can update share network info. " msgstr "Aqui você pode atualizar as informações da rede de compartilhamento." msgid "From here you can update the default share quotas (max limits)." msgstr "" "Aqui você pode atualizar a quota de compartilhamento padrão (limites " "máximos)." msgid "Get Migration Progress" msgstr "Obter o Progresso da Migração" msgid "Get migration progress" msgstr "Obter progresso da migração" msgid "GiB" msgstr "GiB" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "Encontrado valor impróprio para o campo 'driver_options'. Esperados apenas " "pares de chave=valor." msgid "Group specs" msgstr "Especificações do Grupo" msgid "Here can be modified extra-specs for share type." msgstr "" "Aqui podem ser modificadas as extra-specs para o tipo de compartilhamento." msgid "Here can be modified group-specs for share group type." msgstr "" "Aqui pode ser modificado o group-specs para o tipo de grupo de " "compartilhamento." msgid "Host" msgstr "Host" msgid "Host of share" msgstr "Host do compartilhamento" msgid "Host to migrate share" msgstr "Host para migrar o compartilhamento" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "" "Host onde o compartilhamento está localizado, exemplo: algum." "host@driver[#pool]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "Versão do IP" msgid "Id" msgstr "Id" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "Valor incorreto configurado para as especificações extras exigidas " "'spec_driver_handles_share_servers'. Valores permitidos são %s. Case " "insensitive." msgctxt "Current status of share server" msgid "In-use" msgstr "Em uso" msgctxt "Current status of snapshot" msgid "In-use" msgstr "Em uso" msgctxt "Current status of share network" msgid "Inactive" msgstr "Inativo" #, python-format msgid "Key '%s' has improper length." msgstr "Chave '%s' possui tamanho impróprio." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Chave não pode conter espaços. Veja string '%s'." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Chaves não devem conter espaços. Erro em '%s'." msgid "Limit" msgstr "Limite" msgid "Manage" msgstr "Gerenciar" msgctxt "Current status of share" msgid "Manage Error" msgstr "Erro no Gerenciamento" msgid "Manage Replicas" msgstr "Gerenciar Réplicas" msgid "Manage Rules" msgstr "Gerenciar regras" msgid "Manage Share" msgstr "Gerenciar Compartilhamento" msgid "Manage Share Group Type Access" msgstr "Gerenciar Acesso do Tipo de Grupo de Compartilhamento" msgid "Manage Share Snapshot Rules" msgstr "Gerenciar Regras de Snapshot de Compartilhamento" msgid "Manage Share Type Access" msgstr "Gerenciar Acesso do Tipo de Compartilhamento" msgid "Metadata" msgstr "Metadado" msgid "Migrate Share" msgstr "Migrar Compartilhamento" msgid "Migrate a Share" msgstr "Migrar um Compartilhamento" msgctxt "Current status of share" msgid "Migrating" msgstr "Migrando" msgctxt "Current status of share" msgid "Migrating to" msgstr "Migrando para" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "A migração do compartilhamento %(name)s está em %(progress)s porcento." msgid "Mount snapshot support" msgstr "Suporte à montagem de snapshot" msgid "Name" msgstr "Nome" msgid "Net Details" msgstr "Detalhes da Rede" msgid "Network" msgstr "Rede" msgid "Network Type" msgstr "Tipo de Rede" msgid "Networks" msgstr "Redes" msgid "Neutron Net" msgstr "Rede Neutron" msgid "Neutron Subnet" msgstr "Sub-rede Neutron." msgid "New Size (GiB)" msgstr "Novo Tamanho (GiB)" msgid "New share network to be set in migrated share" msgstr "" "Nova rede de compartilhamento a ser configurada no compartilhamento migrado" msgid "New share type to be set in migrating share" msgstr "" "Novo tipo de compartilhamento a ser configurado no compartilhamento de " "migração." msgid "No projects found." msgstr "Nenhum projeto encontrado." msgid "No projects selected." msgstr "Nenhum projeto selecionado." msgid "No security services found." msgstr "Nenhum serviço de segurança foi encontrado." msgid "No security services selected." msgstr "Nenhum serviço de segurança foi selecionado." msgid "No source, empty share" msgstr "Sem origem, compartilhamento vazio" msgid "No source, empty share group" msgstr "Nenhuma origem, grupo de compartilhamento vazio" msgid "Nondisruptive" msgstr "Não disruptivo" msgid "Number of Share Snapshots" msgstr "Número de Snapshots de Compartilhamento" msgid "Number of Shares" msgstr "Número de Compartilhamentos" msgid "Obtain Progress" msgstr "Obter Progresso" msgid "Obtain migration progress of a Share" msgstr "Obter progresso da migração de um Compartilhamento" msgid "One line - one action. Empty strings will be ignored." msgstr "Uma linha - uma ação. Sequências vazias serão ignoradas." msgid "Overview" msgstr "Visão Geral" msgid "Password" msgstr "Senha" msgid "Passwords do not match." msgstr "As senhas não correspondem." msgid "Preserve Metadata" msgstr "Preservar Metadados" msgid "Preserve Snapshots" msgstr "Preservar Snapshots" msgid "Project" msgstr "Projeto" msgid "Projects with access to share group type" msgstr "Projetos com acesso a tipo de grupo de compartilhamento" msgid "Projects with access to share type" msgstr "Projetos com acesso a tipo de compartilhamento" msgid "Protocol" msgstr "Protocolo" msgid "Public" msgstr "Público" msgid "Quota Name" msgstr "Nome da Quota" msgid "Replica Details" msgstr "Detalhes da Réplica" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Detalhes da Réplica: %(replica_display_name)s" msgid "Replica State" msgstr "Estado da Réplica" msgid "Replica state" msgstr "Estado da Réplica" msgid "Replicas" msgstr "Réplicas" msgid "Reset Replica State" msgstr "Resetar o Estado da Réplica" msgid "Reset Replica Status" msgstr "Resetar o Status da Réplica" msgid "Reset Share Group Snapshot Status" msgstr "Redefinir o Status do Snapshot do Grupo de Compartilhamento" msgid "Reset Share Group Status" msgstr "Redefinir o Status do Grupo de Compartilhamento" msgid "Reset Status" msgstr "Redefinir Status" msgid "Reset replica state" msgstr "Resincronizar estado da réplica" msgid "Reset replica status" msgstr "Resetar o status da réplica" msgid "Reset share replica's state with ID" msgstr "Resetar o estado da réplica de compartilhamento com ID" msgid "Reset share replica's status with ID" msgstr "Resetar o status da réplica de compartilhamento com ID" msgid "Reset state" msgstr "Redefinir estado" msgid "Reset status" msgstr "Redefinir status" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "Resetando o estado da réplica ('%(id)s') de '%(from)s' para '%(to)s'. " #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "Resetando o status da réplica ('%(id)s') de '%(from)s' para '%(to)s'. " #, python-format msgid "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Redefinindo o status do grupo de compartilhamento ('%(id)s') de '%(from)s' " "para '%(to)s'." #, python-format msgid "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Redefinindo o status do snapshot do grupo de compartilhamento ('%(id)s') de " "'%(from)s' para '%(to)s'." msgid "Resync" msgstr "Resincronizar" msgid "Resync Replica" msgstr "Ressincronizar Réplica" msgid "Resync replica" msgstr "Resincronizar réplica" msgid "Resync share replica with ID" msgstr "Ressincronizar réplica de compartilhamento com ID" #, python-format msgid "Resync'ing replica '%s'" msgstr "Ressincronizando réplica '%s'" msgid "Revert Share" msgstr "Reverter Compartilhamento" msgid "Revert Share to a Snapshot" msgstr "Reverter Compartilhamento para um Snapshot" msgid "Revert share to a snapshot" msgstr "Reverter compartilhamento para um snapshot" msgctxt "Current status of share" msgid "Reverting Error" msgstr "Reversão de Erro" msgid "Rules" msgstr "Regras" msgid "Save Changes" msgstr "Salvar Alterações" msgid "Security Service Details" msgstr "Detalhes do Serviço de Segurança" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Detalhes do Serviço de Segurança: %(service_display_name)s" msgid "Security Service Overview" msgstr "Visão Geral do Serviço de Segurança" msgid "Security Services" msgstr "Serviços de segurança" msgid "Security services within share network" msgstr "Serviços de segurança dentro da rede de compartilhamento" msgid "Segmentation Id" msgstr "ID de Segmentação" msgid "Select parameters of share group you want to create. " msgstr "" "Selecionar parâmetros do grupo de compartilhamento que você deseja criar." msgid "Select parameters of share you want to create. " msgstr "Selecionar parâmetros de compartilhamento que você deseja criar." msgid "Selected Networks" msgstr "Redes Selecionadas" msgid "Selected Projects" msgstr "Projetos Selecionados." msgid "Selected projects" msgstr "Projetos selecionados" msgid "Selected security services" msgstr "Serviços de segurança selecionados" msgid "Server" msgstr "Servidor" msgid "Set Replica as Active" msgstr "Definir Réplica como Ativa" msgid "Set as Active" msgstr "Definir como Ativo" msgid "Set maximum quotas for the project." msgstr "Defina o valor máximo para as cotas do projeto." msgid "Set share replica with ID" msgstr "Definir réplica de compartilhamento com ID" #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Definindo réplica \"%s\" como ativa..." msgid "Share" msgstr "Compartilhamento" #, python-format msgid "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgstr "" "O compartilhamento \"%(s)s\" foi revertido com sucesso para snapshot \"%(ss)s" "\"" msgid "Share Details" msgstr "Detalhes do Compartilhamento" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Detalhes do Compartilhamento: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Detalhes do Compartilhamento: %(share_name)s" msgid "Share Group" msgstr "Grupo de Compartilhamento" msgid "Share Group Details" msgstr "Detalhes do Grupo de Compartilhamento" #, python-format msgid "Share Group Details: %s" msgstr "Detalhes do Grupo de Compartilhamento:%s" msgid "Share Group Name" msgstr "Nome do Grupo de Compartilhamento" msgid "Share Group Overview" msgstr "Visão Geral de Grupo de Compartilhamento" msgid "Share Group Snapshot" msgstr "Snapshot de Grupo de Compartilhamento" msgid "Share Group Snapshot Details" msgstr "Detalhes do Snapshot do Grupo de Compartilhamento" #, python-format msgid "Share Group Snapshot Details: %(sgs_display_name)s" msgstr "" "Detalhes do Snapshot do Grupo de Compartilhamento: %(sgs_display_name)s" msgid "Share Group Snapshot Overview" msgstr "Visão Geral de Snapshot de Grupo de Compartilhamento" msgid "Share Group Snapshots" msgstr "Snapshots de Grupo de Compartilhamento" msgid "Share Group Type" msgstr "Tipo do Grupo de Compartilhamento" msgid "Share Group Types" msgstr "Tipos de Grupo de Compartilhamento" msgid "Share Groups" msgstr "Grupos de Compartilhamento" msgid "Share ID" msgstr "ID do Compartilhamento" msgid "Share Instance Details" msgstr "Detalhes da Instância de Compartilhamento" #, python-format msgid "Share Instance Details: %s" msgstr "Detalhes da Instância de Compartilhamento: %s" msgid "Share Instance Overview" msgstr "Visão Geral de Instância de Compartilhamento" msgid "Share Instances" msgstr "Instâncias de Compartilhamento" msgid "Share Limits" msgstr "Limites de Compartilhamento" msgid "Share Name" msgstr "Nome do Compartilhamento" msgid "Share Network" msgstr "Rede de Compartilhamento" msgid "Share Network Details" msgstr "Detalhes da Rede de Compartilhamento" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Detalhes da Rede de Compartilhamento: %(network_display_name)s" msgid "Share Network Info" msgstr "Informação da Rede de Compartilhamento" msgid "Share Network Overview" msgstr "Visão Geral da Rede de Compartilhamento" msgid "Share Networks" msgstr "Redes de Compartilhamento" msgid "Share Overview" msgstr "Visão Geral do Compartilhamento" msgid "Share Protocol" msgstr "Protocolo de Compartilhamento" msgid "Share Quotas" msgstr "Quotas de Compartilhamento" msgid "Share Replica Overview" msgstr "Visão Geral de Réplica de Compartilhamento" msgid "Share Replicas" msgstr "Réplicas de Compartilhamento" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Réplicas de Compartilhamento: %(share_display_name)s" msgid "Share Rules" msgstr "Regras de Compartilhamento" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Regras do Compartilhamento: %(share_display_name)s" msgid "Share Server" msgstr "Servidor de Compartilhamento" msgid "Share Server Details" msgstr "Detalhes do Servidor de Compartilhamento" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Detalhes do Servidor de Compartilhamento: %(server_name)s" msgid "Share Server Id" msgstr "ID do Servidor de Compartilhamento" msgid "Share Server Overview" msgstr "Visão Geral de Servidor de Compartilhamento" msgid "Share Servers" msgstr "Servidores de Compartilhamento" msgid "Share Snapshot Details" msgstr "Detalhes do Snapshot de Compartilhamento" msgid "Share Snapshot Name" msgstr "Nome do Snapshot de Compartilhamento" msgid "Share Snapshot Overview" msgstr "Visão Geral de Snapshot de Compartilhamento" msgid "Share Snapshot Rules" msgstr "Regras de Snapshot de Compartilhamento" msgid "Share Snapshots" msgstr "Snapshots do Compartilhamento" msgid "Share Snapshots Storage" msgstr "Armazenamento de Snapshots do Compartilhamento" msgid "" "Share Snapshots are used for storing share changes and creating shares. " msgstr "" "Snapshots de Compartilhamento são usados para armazenamento de mudanças de " "compartilhamento e criação de compartilhamentos." msgid "Share Source" msgstr "Origem do Compartilhamento" msgid "Share Storage" msgstr "Armazenamento do Compartilhamento" msgid "Share Type" msgstr "Tipo de Compartilhamento" msgid "Share Types" msgstr "Tipos de Compartilhamento" msgid "Share Types (multiple available)" msgstr "Tipos de Compartilhamento (vários disponíveis)" msgid "Share Types (one available)" msgstr "Tipos de Compartilhamento (um disponível)" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "O compartilhamento não pode ser estendido a %(req)iGiB porque você tem " "apenas %(avail)iGiB da sua cota disponível." msgid "Share gigabytes" msgstr "Gigabytes de Compartilhamento" msgid "Share name to be assigned" msgstr "Nome do compartilhamento a ser atribuído" msgid "Share network" msgstr "Rede de compartilhamento" #, python-format msgid "Share replica %s has been deleted." msgstr "Réplica compartilhada %s foi excluída." msgid "Share server" msgstr "Servidor de compartilhamento" #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "" "O tamanho do compartilhamento deve ser igual ou maior do que o tamanho do " "snapshot (%sGiB)" msgid "Share snapshot gigabytes" msgstr "Gigabytes de snapshot de compartilhamento" msgid "Share snapshots" msgstr "Snapshots de compartilhamento" msgid "Share type" msgstr "Tipo de Compartilhamento" msgid "Share types" msgstr "Tipos de Compartilhamento" msgid "Shared Quotas" msgstr "Quotas Compartilhadas" msgid "Shares" msgstr "Compartilhamentos" msgid "Shares on this server" msgstr "Compartilhamentos neste servidor" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Tamanho" msgid "Size (GiB)" msgstr "Tamanho (GiB)" msgid "Snapshot" msgstr "Snapshot" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Detalhes do Snapshot: %(snapshot_display_name)s" msgid "Snapshot ID" msgstr "ID do SnapShot" msgid "Snapshot Overview" msgstr "Visão Geral de Snapshot" #, python-format msgid "Snapshot Rules: %(snapshot_display_name)s" msgstr "Regras de Snapshot: %(snapshot_display_name)s" msgid "Source" msgstr "Origem" msgid "Source SG Snapshot" msgstr "Snapshot de Origem do Grupo de Compartilhamento" msgid "Source Share Group" msgstr "Grupo de Compartilhamento Fonte" msgid "Source Share Group Snapshot" msgstr "Snapshot de Origem do Grupo de Compartilhamento" msgid "Source Type" msgstr "Tipo de Origem" msgid "Source share group snapshot" msgstr "Snapshot fonte do grupo de compartilhamento" msgid "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgstr "" "Especifique a nova rede de compartilhamento para o compartilhamento. Não " "especifique esse parâmetro se o compartilhamento de migração tiver que ser " "retido na sua rede de compartilhamento atual." msgid "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgstr "" "Especifique o novo de tipo de compartilhamento para o compartilhamento. Não " "especifique esse parâmetro se o compartilhamento de migração tiver que ser " "retido com seu tipo de compartilhamento atual." msgid "Specs" msgstr "Especificações" msgid "Start migration" msgstr "Iniciar migração" msgid "Status" msgstr "Status" msgid "Submit" msgstr "Enviar" msgid "Subnet" msgstr "Sub-rede" #, python-format msgid "Successfully created security service: %s" msgstr "Serviço de segurança criado com sucesso: %s" #, python-format msgid "Successfully created share group type: %s" msgstr "Tipo de grupo de compartilhamento criado com sucesso: %s" #, python-format msgid "Successfully created share network: %s" msgstr "Rede de compartilhamento criada com sucesso: %s" #, python-format msgid "Successfully created share type: %s" msgstr "Tipo de compartilhamento criado com sucesso: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "" "Enviada com sucesso a requisição de cancelamento da migração do " "compartilhamento: %s." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "" "Enviada com sucesso a requisição para completar a migração do " "compartilhamento: %s." #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Enviada com sucesso a requisição para gerenciar o compartilhamento: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "Enviada com sucesso a requisição para migrar o compartilhamento: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "" "Solicitação enviada com sucesso para tornar o compartilhamento não " "gerenciado: %s" #, python-format msgid "Successfully updated group specs for share group type '%s'." msgstr "" "Especificações de grupo atualizadas com sucesso para o tipo de grupo de " "compartilhamento '%s'." #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Serviço de segurança \"%s\" atualizado com sucesso " msgid "Task state" msgstr "Estado da tarefa" msgid "" "The share group type defines the characteristics of a share group backend." msgstr "" "O tipo de grupo de compartilhamento define as características do backend de " "um grupo de compartilhamento." #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "" "O tamanho do compartilhamento não pode ser menor que o tamanho do snapshot " "(%sGiB)" msgid "The share type defines the characteristics of a share backend." msgstr "" "O tipo de compartilhamento define as características de um backend de " "compartilhamento." msgid "To add extra-specs use:" msgstr "Para adicionar extra-specs utilize:" msgid "To add group-specs use:" msgstr "Para adicionar group-specs utilize:" msgid "To add metadata use:" msgstr "Para adicionar metadados utilize:" msgid "To unset extra-specs use:" msgstr "Para desconfigurar as extra-specs utilize:" msgid "To unset group-specs use:" msgstr "Para desconfigurar group-specs use:" msgid "To unset metadata use:" msgstr "Para desconfigurar os metadados utilize:" msgid "Total Gibibytes" msgstr "Total de Gibibytes" msgid "Type" msgstr "Tipo" msgid "Unable to add rule." msgstr "Não foi possível adicionar a regra." msgid "Unable to add snapshot rule." msgstr "Não é possível adicionar regra de snapshot." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "" "Não foi possível cancelar migração do compartilhamento %s neste momento." #, python-format msgid "Unable to complete migration of share %s." msgstr "Não é possível completar a migração do compartilhamento %s." msgid "Unable to create security service." msgstr "Não foi possível criar o serviço de segurança: %s" msgid "Unable to create share group snapshot." msgstr "Não é possível criar snapshot de grupo de compartilhamento." msgid "Unable to create share group type." msgstr "Não é possível criar o tipo de grupo de compartilhamento." msgid "Unable to create share group." msgstr "Não é possível criar o grupo de compartilhamento." msgid "Unable to create share network." msgstr "Não é possível criar a rede de compartilhamento." msgid "Unable to create share replica." msgstr "Não é possível criar réplica de compartilhamento." msgid "Unable to create share snapshot." msgstr "Não foi possível criar um snapshot do compartilhamento." msgid "Unable to create share type." msgstr "Não é possível criar tipo de compartilhamento." msgid "Unable to create share." msgstr "Não foi possível criar o compartilhamento." #, python-format msgid "Unable to create share. %s" msgstr "Não é possível criar compartilhamento. %s" #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Não é possível excluir a réplica \"%s\"." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Não foi possível excluir regra \"%s\"." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Não é possível excluir o compartilhamento \"%s\"." #, python-format msgid "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." msgstr "" "Não é possível excluir o snapshot do grupo de compartilhamento \"%s\". Um ou " "mais grupos de compartilhamento dependem dele." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "Não é possível excluir o snapshot \"%s\". um ou mais compartilhamentos " "dependem dele." #, python-format msgid "Unable to delete snapshot rule \"%s\"." msgstr "Não é possível excluir regra de snapshot \"%s\"." msgid "Unable to get information about share group type access." msgstr "" "Não é possível obter informações sobre o acesso dos tipos de grupo de " "compartilhamento." msgid "Unable to get information about share type access." msgstr "" "Não é possível obter informações sobre o acesso do tipo de compartilhamento." msgid "Unable to get list of projects." msgstr "Não é possível recuperar lista de projetos." msgid "Unable to get manila default quota." msgstr "Não é possível obter a quota padrão do manila." msgid "Unable to get the security services hosts" msgstr "Não é possível obter os hosts de serviços de segurança" #, python-format msgid "Unable to get the specified share group '%s' for snapshot creation." msgstr "" "Não é possível obter o grupo de compartilhamento especificado '%s' para a " "criação do snapshot." msgid "Unable to load the specified share group snapshot." msgstr "" "Não é possível carregar o snapshot de grupo de compartilhamento especificado." msgid "Unable to load the specified snapshot." msgstr "Não é possível carregar o snapshot especificado." msgid "Unable to manage share" msgstr "Não foi possível gerenciar o compartilhamento" #, python-format msgid "Unable to migrate share %s." msgstr "Não foi possível migrar compartilhamento %s." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "" "Não é possível obter o progresso da migração do compartilhamento %s nesse " "momento." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "Não é possível resetar o estado da réplica '%s'." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "Não é possível resetar o status da réplica '%s'." #, python-format msgid "Unable to reset status of share group '%s'." msgstr "Não e possível redefinir o status do grupo de compartilhamento '%s'." #, python-format msgid "Unable to reset status of share group snapshot '%s'." msgstr "" "Não é possível redefinir o status do snapshot do grupo de compartilhamento " "'%s'." #, python-format msgid "Unable to resync replica '%s'." msgstr "Não é possível ressincronizar réplica '%s'." msgid "Unable to retrieve default share quotas." msgstr "Não é possível obter a quota de compartilhamento padrão." msgid "Unable to retrieve list of projects." msgstr "Não é possível recuperar lista de projetos." msgid "Unable to retrieve quotas." msgstr "Não foi possível recuperar cotas." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Não foi possível recuperar a réplica '%s'." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Não é possível obter os detalhes do serviço de segurança '%s'." msgid "Unable to retrieve security services" msgstr "Não é possível recuperar serviços de segurança" msgid "Unable to retrieve security_service." msgstr "Não é possível recuperar o security_service." msgid "Unable to retrieve share details." msgstr "Não é possível obter os detalhes do compartilhamento." #, python-format msgid "Unable to retrieve share group '%s'." msgstr "Não é possível obter o grupo de compartilhamento '%s'" msgid "Unable to retrieve share group details." msgstr "Não é possível obter os detalhes do grupo de compartilhamento." #, python-format msgid "Unable to retrieve share group snapshot '%s'." msgstr "Não é possível recuperar o snapshot do grupo de compartilhamento '%s'." msgid "Unable to retrieve share group snapshot details." msgstr "" "Não é possível obter os detalhes do snapshot do grupo de compartilhamento." msgid "Unable to retrieve share group snapshot list." msgstr "Não é possível obter a lista de snapshot de grupo de compartilhamento." msgid "Unable to retrieve share group snapshot." msgstr "Não é possível obter o snapshot do grupo de compartilhamento." msgid "Unable to retrieve share group snapshots." msgstr "Não é possível obter os snapshots de grupo de compartilhamento." msgid "Unable to retrieve share group types." msgstr "Não é possível obter os tipos de grupos de compartilhamento." msgid "Unable to retrieve share group." msgstr "Não é possível obter o grupo de compartilhamento." msgid "Unable to retrieve share groups." msgstr "Não é possível obter grupos de compartilhamento." msgid "Unable to retrieve share instance details." msgstr "Não foi possível obter os detalhes da instância de compartilhamento." msgid "Unable to retrieve share instances." msgstr "Não foi possível recuperar instâncias de compartilhamento." msgid "Unable to retrieve share limit information." msgstr "Não foi possível recuperar informações de limite de compartilhamento." msgid "Unable to retrieve share list." msgstr "Não é possível recuperar a lista de compartilhamento." msgid "Unable to retrieve share network details." msgstr "Não foi possível obter os detalhes da rede de compartilhamento." msgid "Unable to retrieve share network." msgstr "Não foi possível recuperar rede de compartilhamento." msgid "Unable to retrieve share networks" msgstr "Não foi possível recuperar redes de compartilhamento" msgid "Unable to retrieve share replicas." msgstr "Não foi possível recuperar réplicas de compartilhamento." msgid "Unable to retrieve share rules." msgstr "Não foi possível recuperar regras do compartilhamento." msgid "Unable to retrieve share server details." msgstr "Não foi possível obter os detalhes do servidor de compartilhamento." msgid "Unable to retrieve share servers" msgstr "Não foi possível recuperar servidores de compartilhamento" msgid "Unable to retrieve share snapshot list." msgstr "Não é possível obter a lista de snapshot de compartilhamento." msgid "Unable to retrieve share snapshot rules." msgstr "Não é possível obter as regras de snapshot de compartilhamento." msgid "Unable to retrieve share snapshot." msgstr "Não é possível obter o snapshot de compartilhamento." msgid "Unable to retrieve share snapshots list." msgstr "Não foi possível recuperar a lista de snapshots." msgid "Unable to retrieve share snapshots." msgstr "Não é possível obter snapshots de compartilhamento." msgid "Unable to retrieve share types." msgstr "Não é possível obter tipos de compartilhamento." msgid "Unable to retrieve share." msgstr "Não foi possível recuperar compartilhamento." #, python-format msgid "Unable to retrieve share. %s" msgstr "Não foi possível recuperar compartilhamento. %s" msgid "Unable to retrieve share_gruop_type." msgstr "Não é possível obter share_group_type." msgid "Unable to retrieve share_type." msgstr "Não foi possível recuperar o share_type." msgid "Unable to retrieve snapshot details." msgstr "Não é possível recuperar detalhes do snapshot." msgid "Unable to retrieve snapshot." msgstr "Não foi possível recuperar o snapshot." msgid "Unable to retrieve volume details." msgstr "Não foi possível recuperar detalhes do volume." msgid "Unable to revert share to the snapshot." msgstr "Não é possível reverter o compartilhamento para o snapshot." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Não foi possível definir a réplica '%s' como ativa." msgid "Unable to unmanage share." msgstr "Não foi possível tornar o compartilhamento não gerenciado." #, python-format msgid "Unable to update access for share group type \"%s\"." msgstr "" "Não é possível atualizar acessos para o tipo de grupo de compartilhamento " "\"%s\"." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "" "Não é possível atualizar o acesso para o tipo de compartilhamento \"%s\"." msgid "Unable to update default quotas." msgstr "Não é possível atualizar cotas padrão." msgid "Unable to update group_specs for share group type." msgstr "" "Não é possível atualizar group_specs para o tipo de grupo de " "compartilhamento." msgid "Unable to update security service." msgstr "Não foi possível atualizar o serviço de segurança." msgid "Unable to update share group snapshot." msgstr "Não é possível atualizar o snapshot do grupo de compartilhamento." msgid "Unable to update share group type." msgstr "Não é possível atualizar o tipo de grupo de compartilhamento." msgid "Unable to update share group." msgstr "Não é possível atualizar o grupo de compartilhamento." msgid "Unable to update share metadata." msgstr "Não foi possível atualizar metadados de compartilhamento." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Não é possível atualizar a rede de compartilhamento \"%s\"." msgid "Unable to update share network." msgstr "Não foi possível atualizar rede de compartilhamento." msgid "Unable to update share snapshot." msgstr "Não é possível atualizar snapshot de compartilhamento." msgid "Unable to update share type." msgstr "Não é possível atualizar o tipo de acesso." msgid "Unable to update share." msgstr "Não foi possível atualizar o compartilhamento." msgid "Unknown" msgstr "Desconhecido" msgid "Unmanage" msgstr "Remoção de Gerenciamento" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Erro na Remoção de Gerenciamento" msgid "Unmanage Share" msgstr "Remover Gerenciamento de Compartilhamento" msgid "Update" msgstr "Atualizar" msgid "Update Share Group" msgstr "Atualizar Grupo de Compartilhamento" msgid "Update Share Group Snapshot" msgstr "Atualizar Snapshot do Grupo de Compartilhamento" msgid "Update Share Group Type" msgstr "Atualizar Tipo de Grupo de Compartilhamento" msgid "Update Share Network" msgstr "Atualizar Rede de Compartilhamento" msgid "Update Share Snapshot" msgstr "Atualizar Snapshot de Compartilhamento" msgid "Update Share Type" msgstr "Atualizar Tipo de Compartilhamento" msgid "Update Share group Type" msgstr "Atualizar o Tipo do Grupo de Compartilhamento" msgid "Update share network" msgstr "Atualizar rede de compartilhamento." msgid "Updated" msgstr "Atualizado" msgid "Updated At" msgstr "Atualizado em" #, python-format msgid "Updated access for share group type \"%s\"." msgstr "Acesso atualizado para o tipo de grupo de compartilhamento \"%s\"." #, python-format msgid "Updated access for share type \"%s\"." msgstr "Acesso atualizado para o tipo de compartilhamento \"%s\"." #, python-format msgid "Updated share network \"%s\"." msgstr "Rede de compartilhamento atualizada \"%s\"." #, python-format msgid "Updating share \"%s\"" msgstr "Atualizando o compartilhamento \"%s\"" #, python-format msgid "Updating share group \"%s\"" msgstr "Atualizando grupo de compartilhamento \"%s\"" #, python-format msgid "Updating share group snapshot \"%s\"" msgstr "Atualizando o snapshot de grupo de compartilhamento \"%s\"" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Atualizando os metadados do compartilhamento \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Atualizando rede de compartilhamento \"%s\"" #, python-format msgid "Updating share snapshot \"%s\"" msgstr "Atualizando snapshot de compartilhamento \"%s\"" msgid "Use share group snapshot as a source" msgstr "Usar snapshot de grupo de compartilhamento como origem" msgid "Use snapshot as a source" msgstr "Utilizar snapshot como origem." msgid "User" msgstr "Usuário" msgid "Visibility" msgstr "Visibilidade" msgid "Writable" msgstr "Gravável" msgid "as Active?" msgstr "como Ativo?" msgid "key=value pairs per line can be set" msgstr "Pares de chave=valor por linha pode ser configurado" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/ru/0000775000175000017500000000000000000000000017313 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/ru/LC_MESSAGES/0000775000175000017500000000000000000000000021100 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/ru/LC_MESSAGES/django.po0000664000175000017500000007474100000000000022717 0ustar00zuulzuul00000000000000# Aleksey Alekseenko <9118250541@mail.ru>, 2016. #zanata # Alexander , 2016. #zanata # Artem , 2016. #zanata # Ilya Alekseyev , 2016. #zanata # Ivan Startsev , 2016. #zanata # Valentin Chikunov , 2016. #zanata # Valeriy Ponomaryov , 2016. #zanata # Artem , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-02-06 02:19+0000\n" "Last-Translator: Artem \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" #, python-format msgid "%sGiB" msgstr "%s ГиБ" msgid "(Quota exceeded)" msgstr "(Превышена квота)" msgid "Access Key" msgstr "Ключ доступа" msgid "Access Level" msgstr "Уровень доступа" msgid "Access To" msgstr "Доступ к" msgid "Access Type" msgstr "Тип доступа" msgid "Access to" msgstr "Доступ к" msgctxt "Current status of share network" msgid "Active" msgstr "Активный" msgctxt "Current status of share server" msgid "Active" msgstr "Активный" msgid "Add" msgstr "Добавить" msgid "Add Rule" msgstr "Добавить правило" msgid "Add Security Service" msgstr "Добавить службу безопасности" msgid "Add rule" msgstr "Добавить правило" msgid "Add security services to share network." msgstr "Добавить службы безопасности в сеть общего ресурса." msgid "All keys and values must be in range from 1 to 255." msgstr "Все ключи и значения должны быть в диапазоне от 1 до 255" msgid "Allow project access to share type." msgstr "Разрешить проектам доступ к типу общего ресурса." msgid "At least one security service must be specified." msgstr "По крайней мере одна служба безопасности должна быть определена." msgid "Availability Zone" msgstr "Зона доступности" msgid "Availability zone" msgstr "Зона доступности" msgctxt "Current status of replica" msgid "Available" msgstr "Доступна" msgctxt "Current status of share" msgid "Available" msgstr "Доступен" msgctxt "Current status of snapshot" msgid "Available" msgstr "Доступно" msgid "Available projects" msgstr "Доступные проекты" msgid "Available security services" msgstr "Доступные службы безопасности." msgid "Cancel Migration" msgstr "Отменить миграцию" msgid "Cancel migration" msgstr "Отменить миграцию" msgid "Cancel migration of a Share" msgstr "Отменить миграцию общего ресурса" msgid "Choose a snapshot" msgstr "Выберете снимок" msgid "Complete Migration" msgstr "Завершите миграцию" msgid "Complete migration" msgstr "Завершить миграцию" msgid "Complete migration of a Share" msgstr "Завершите миграцию общего ресурса" msgid "Confirm Migration Cancelling of Share" msgstr "Подтвердите отмену миграции общего ресурса" msgid "Confirm Migration Completion of Share" msgstr "Подтвердите завершение миграции общего ресурса" msgid "Confirm Obtaining migration progress of Share" msgstr "Подтвердите получение информации о прогрессе миграции общего ресурса" msgid "Confirm Password" msgstr "Подтвердите пароль" msgid "Confirm Unmanage Share" msgstr "Подтвердить разрегистрацию общего ресурса" msgid "Create" msgstr "Создать" msgid "Create Replica" msgstr "Создать реплику" msgid "Create Security Service" msgstr "Создать службу безопасности" msgid "Create Share" msgstr "Создать общий ресурс" msgid "Create Share Network" msgstr "Создать сеть общего ресурса" msgid "Create Share Snapshot" msgstr "Создать снимок общего ресурса" msgid "Create Share Type" msgstr "Создать тип общего ресурса" msgid "Create a Share" msgstr "Создать общий ресурс" msgid "Created At" msgstr "Создано" msgctxt "Current status of replica" msgid "Creating" msgstr "Создание" msgctxt "Current status of share" msgid "Creating" msgstr "Создание" msgctxt "Current status of share server" msgid "Creating" msgstr "Создание" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Создание" #, python-format msgid "Creating replica for share \"%s\"." msgstr "Создание реплики общего ресурса \"%s\"." #, python-format msgid "Creating rule for \"%s\"" msgstr "Создние правила для \"%s\"" #, python-format msgid "Creating share \"%s\"" msgstr "Создание общего ресурса \"%s\"" #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Создается снимок общего ресурса \"%s\"." msgid "Current Size (GiB)" msgstr "Текущий размер (ГиБ)" msgid "DNS IP" msgstr "DNS IP" msgctxt "Current status of replica" msgid "Deleting" msgstr "Удаление" msgctxt "Current status of share" msgid "Deleting" msgstr "Удаление" msgid "Description" msgstr "Описание" msgid "Domain" msgstr "Домен" msgid "Driver handles share servers" msgstr "Драйвер обрабатывает сервера общих ресурсов" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Параметры драйвера ('volume_id' для 'generic' драйвера и т.д.)" #, python-format msgid "Duplicated keys '%s'." msgstr "Повторяющийся ключ '%s'" msgid "Edit" msgstr "Изменить" msgid "Edit Security Service" msgstr "Редактировать службу безопасности" msgid "Edit Share" msgstr "Редактировать общий ресурс" msgid "Edit Share Metadata" msgstr "Редактировать метаданные общего ресурса" msgid "Edit Share Network" msgstr "Редактировать сеть общего ресурса" msgctxt "Current status of replica" msgid "Error" msgstr "Ошибка" msgctxt "Current status of share" msgid "Error" msgstr "Ошибка" msgctxt "Current status of share network" msgid "Error" msgstr "Ошибка" msgctxt "Current status of share server" msgid "Error" msgstr "Ошибка" msgctxt "Current status of snapshot" msgid "Error" msgstr "Ошибка" msgid "Expected only pairs of key=value." msgstr "Ожидаются только пары ключ = значение" msgid "Export location" msgstr "Место экспорта" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "Место экспорта общего ресурса. Пример для NFS: 1.2.3.4:/path/to/share" msgctxt "Current status of share" msgid "Extending Error" msgstr "Ошибка расширения общего ресурса" msgid "Extra specs" msgstr "Доп. параметры" msgid "Force Host Assisted Migration" msgstr "Принудительно использовать хост для миграции" msgid "From here you can update share network info. " msgstr "Здесь вы можете обновить информацию о сети общего ресурса." msgid "Get migration progress" msgstr "Получить статус миграции" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "Получено неверное значение для поля 'driver_options'. Ожидаются только пары " "ключ = значение" msgid "Host" msgstr "Хост" msgid "Host of share" msgstr "Хост общего ресурса" msgid "Host to migrate share" msgstr "Хост для миграции общего ресурса" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "" "Хост на котором расположен общий ресурс, например: some.host@driver[#pool]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "Версия IP" msgid "Id" msgstr "ID" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "В требуемый дополнительный параметр 'spec_driver_handles_share_servers' " "выставлено недопустимое значение. Допустимые значения %s. " "Регистронезависимое." msgctxt "Current status of share server" msgid "In-use" msgstr "Используется" msgctxt "Current status of snapshot" msgid "In-use" msgstr "Используется" msgctxt "Current status of share network" msgid "Inactive" msgstr "Неактивный" #, python-format msgid "Key '%s' has improper length." msgstr "Ключ '%s' имеет неподходящую длину" #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Ключ не может содержать пробелы. Смотри строку '%s'" #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Ключ не может содержать пробелы. Ошибка: '%s'" msgid "Manage" msgstr "Управление" msgctxt "Current status of share" msgid "Manage Error" msgstr "Ошибка регистрации" msgid "Manage Replicas" msgstr "Управление репликами общих ресурсов" msgid "Manage Rules" msgstr "Управление правилами" msgid "Manage Share" msgstr "Зарегистрировать общий ресурс" msgid "Manage Share Type Access" msgstr "Управление доступом к типам общих ресурсов" msgid "Metadata" msgstr "Метаданные" msgid "Migrate Share" msgstr "Миграция общего ресурса" msgid "Migrate a Share" msgstr "Мигрировать общий ресурс" msgctxt "Current status of share" msgid "Migrating" msgstr "Миграция" msgctxt "Current status of share" msgid "Migrating to" msgstr "Миграция в" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "Миграция общего ресурса %(name)s выполнена на %(progress)s процентов." msgid "Name" msgstr "Имя" msgid "Network Type" msgstr "Тип сети" msgid "Networks" msgstr "Сети" msgid "Neutron Net" msgstr "Сеть Neutron" msgid "Neutron Subnet" msgstr "Подсеть Neutron " msgid "New Size (GiB)" msgstr "Новый размер (ГиБ)" msgid "New share network to be set in migrated share" msgstr "" "Новая сеть общего ресурса, которая будет назначена мигрируемому общему " "ресурсу" msgid "New share type to be set in migrating share" msgstr "" "Новый тип общего ресурса, который будет назначен мигрируемому общему ресурсу" msgid "No projects found." msgstr "Проекты не найдены." msgid "No projects selected." msgstr "Проекты не выбраны." msgid "No security services found." msgstr "Службы безопасности не найдены." msgid "No security services selected." msgstr "Службы безопасности не выбраны." msgid "No source, empty share" msgstr "Нет источника, пустой общий ресурс" msgid "Obtain Progress" msgstr "Получить информацию о прогрессе" msgid "Obtain migration progress of a Share" msgstr "Получить информацию о прогрессе миграции общего ресурса" msgid "Overview" msgstr "Обзор" msgid "Password" msgstr "Пароль" msgid "Passwords do not match." msgstr "Пароли не совпадают" msgid "Preserve Metadata" msgstr "Сохранить метаданные" msgid "Project" msgstr "Проект" msgid "Projects with access to share type" msgstr "Проекты с доступом к типу общего ресурса" msgid "Protocol" msgstr "Протокол" msgid "Public" msgstr "Публичный" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Информация о реплике: %(replica_display_name)s" msgid "Replica State" msgstr "Состояние реплики" msgid "Replicas" msgstr "Реплики" msgid "Reset Replica State" msgstr "Сбросить состояние реплики" msgid "Reset Replica Status" msgstr "Сбросить статус реплики" msgid "Reset replica state" msgstr "Сбросить состояние реплики" msgid "Reset replica status" msgstr "Сбросить статус реплики" msgid "Reset state" msgstr "Сбросить состояние" msgid "Reset status" msgstr "Сбросить статус" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "Сброс состояния реплики ('%(id)s') с '%(from)s' к '%(to)s'." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "Сброс статуса реплики ('%(id)s') с '%(from)s' до '%(to)s'." msgid "Resync" msgstr "Синхронизировать" msgid "Resync Replica" msgstr "Повторная синхронизация реплики" msgid "Resync replica" msgstr "Повторная синхронизация реплики" #, python-format msgid "Resync'ing replica '%s'" msgstr "Синхронизация реплики '%s'" msgid "Rules" msgstr "Правила" msgid "Save Changes" msgstr "Сохранить изменения" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Информация о службе безопасности: %(service_display_name)s" msgid "Security Services" msgstr "Службы безопасности" msgid "Security services within share network" msgstr "Службы безопасности сети общего ресурса" msgid "Segmentation Id" msgstr "ID сегмента" msgid "Selected projects" msgstr "Выбранные проекты" msgid "Selected security services" msgstr "Выбранные службы безопасности." msgid "Server" msgstr "Сервер" msgid "Set Replica as Active" msgstr "Назначить реплику активной" msgid "Set as Active" msgstr "Назначить активной" msgid "Set maximum quotas for the project." msgstr "Выставите максимальные квоты для этого проекта" #, python-format msgid "Setting replica \"%s\" as active..." msgstr "Назначение реплики \"%s\" активной..." msgid "Share" msgstr "Общий ресурс" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Информация об общем ресурсе: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Информация об общем ресурсе: %(share_name)s" msgid "Share ID" msgstr "ID общего ресурса" #, python-format msgid "Share Instance Details: %s" msgstr "Информация об инстансе общего ресурса: %s" msgid "Share Instances" msgstr "Инстансы общего ресурса" msgid "Share Name" msgstr "Имя общего ресурса" msgid "Share Network" msgstr "Сеть общего ресурса" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Информация о сети общего ресурса: %(network_display_name)s" msgid "Share Network Info" msgstr "Информация о сети общего ресурса" msgid "Share Networks" msgstr "Сети общих ресурсов" msgid "Share Protocol" msgstr "Протокол общего ресурса" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Реплики общего ресурса: %(share_display_name)s" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Правила общего ресурса: %(share_display_name)s" msgid "Share Server" msgstr "Сервер общего ресурса" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Информация о Сервере общего ресурса: %(server_name)s" msgid "Share Server Id" msgstr "ID сервера общего ресурса" msgid "Share Servers" msgstr "Сервера общих ресурсов" msgid "Share Snapshots" msgstr "Снимки общего ресурса" msgid "Share Snapshots Storage" msgstr "Размер хранилица снимков общих ресурсов" msgid "Share Source" msgstr "Источник общего ресурса" msgid "Share Storage" msgstr "Размер хранилища общих ресурсов" msgid "Share Type" msgstr "Тип общего ресурса" msgid "Share Types" msgstr "Типы общих ресурсов" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Невозможно расширить общий ресурс до %(req)i ГиБ, так как ограничение квоты " "составляет %(avail)i ГиБ." msgid "Share name to be assigned" msgstr "Имя общего ресурса, которое будет назначено." #, python-format msgid "Share replica %s has been deleted." msgstr "Реплика общего ресурса %s была удалена." #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "" "Размер общего ресурса должен быть равным или больше размера снимка (%sГиБ)" msgid "Shares" msgstr "Общие ресурсы" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Размер" msgid "Size (GiB)" msgstr "Размер (ГиБ)" msgid "Snapshot" msgstr "Снимок" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Информация о снимке: %(snapshot_display_name)s" msgid "Snapshot Overview" msgstr "Обзор снимка" msgid "Source" msgstr "Источник" msgid "Start migration" msgstr "Начать миграцию" msgid "Status" msgstr "Статус" #, python-format msgid "Successfully created security service: %s" msgstr "Служба безопасности: %s успешно создана" #, python-format msgid "Successfully created share network: %s" msgstr "Сеть общего ресурса: %s успешно создана" #, python-format msgid "Successfully created share type: %s" msgstr "Успешно создан тип общего ресурса: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "Запрос на отмену миграции общего ресурса:%s успешно отправлен." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "Успешно отправлен запрос на завершение миграции общего ресурса :%s" #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Запрос на регистрацию общего ресурса %s успешно отправлен" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "Успешно отправлен запрос на миграцию общего ресурса: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "Успешно отправлен запрос на разрегистрацию общего ресурса: %s" #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Успешно обновлена служба безопасности \"%s\"" #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "Размер общего ресурса не может быть меньше размера снимка (%s ГиБ)" msgid "Type" msgstr "Тип" msgid "Unable to add rule." msgstr "Невозможно добавить правило" #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "Невозможно отменить миграцию общего ресурса %s в данный момент." #, python-format msgid "Unable to complete migration of share %s." msgstr "Невозможно завершить миграцию общего ресурса %s." msgid "Unable to create security service." msgstr "Невозможно создать службу безопасности." msgid "Unable to create share network." msgstr "Невозможно создать сеть общего ресурса." msgid "Unable to create share replica." msgstr "Невозможно создать реплику общего ресурса" msgid "Unable to create share snapshot." msgstr "Не удалось создать снимок общего ресурса." msgid "Unable to create share type." msgstr "Не удалось создать тип общего ресурса." msgid "Unable to create share." msgstr "Не удалось создать общий ресурс." #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Невозможно удалить реплику \"%s\"." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "Не удалось удалить правило \"%s\"." #, python-format msgid "Unable to delete share \"%s\". " msgstr "Невозможно удалить общий ресурс \"%s\"." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "Невозможно удалить снимок \"%s\". Один или несколько общих ресурсов зависят " "от него." msgid "Unable to get information about share type access." msgstr "Невозможно получить информацию о доступе к типу общего ресурса" msgid "Unable to get list of projects." msgstr "Невозможно получить список проектов." msgid "Unable to get the security services hosts" msgstr "Не удается получить хосты служб безопасности" msgid "Unable to load the specified snapshot." msgstr "Не удается загрузить определенный снимок." msgid "Unable to manage share" msgstr "Невозможно зарегистрировать общий ресурс" #, python-format msgid "Unable to migrate share %s." msgstr "Невозможно мигрировать общий ресурс %s." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "" "Сейчас невозможно получить прогресс выполнения миграции общего ресурса: %s " #, python-format msgid "Unable to reset state of replica '%s'." msgstr "Невозможно сбросить состояние реплики '%s'." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "Невозможно сбросить статус реплики '%s'." #, python-format msgid "Unable to resync replica '%s'." msgstr "Невозможно синхронизировать реплику '%s'." msgid "Unable to retrieve list of projects." msgstr "Невозможно получить список проектов." msgid "Unable to retrieve quotas." msgstr "Не удается получить квоты." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Невозможно получить реплику '%s'." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Не удалось получить информацию о службе безопасности '%s'." msgid "Unable to retrieve security services" msgstr "Невозможно получить службы безопасности" msgid "Unable to retrieve security_service." msgstr "Невозможно получить службу безопасности." msgid "Unable to retrieve share details." msgstr "Невозможно получить информацию об общем ресурсе." msgid "Unable to retrieve share instance details." msgstr "Не удалось получить информацию об инстансе общего ресурса." msgid "Unable to retrieve share instances." msgstr "Невозможно получить инстансы общего ресурса." msgid "Unable to retrieve share limit information." msgstr "Не удается получить информацию по ограничениям для общего ресурса. " msgid "Unable to retrieve share list." msgstr "Невозможно получить список общих ресурсов." msgid "Unable to retrieve share network details." msgstr "Невозможно получить информацию о сети общего ресурса" msgid "Unable to retrieve share network." msgstr "Невозможно получить сеть общего ресурса." msgid "Unable to retrieve share networks" msgstr "Невозможно получить сети общех ресурсов" msgid "Unable to retrieve share replicas." msgstr "Невозможно получить реплики общего ресурса." msgid "Unable to retrieve share rules." msgstr "Невозможно получить правила общего ресурса." msgid "Unable to retrieve share server details." msgstr "Невозможно получить информацию о сервере общего ресурса" msgid "Unable to retrieve share servers" msgstr "Невозможно получить сервера общих ресурсов" msgid "Unable to retrieve share snapshots list." msgstr "Невозможно получить список снимков." msgid "Unable to retrieve share snapshots." msgstr "Невозможно получить снимки общего ресурса." msgid "Unable to retrieve share." msgstr "Невозможно получить общий ресурс." #, python-format msgid "Unable to retrieve share. %s" msgstr "Невозможно получить общий ресурс. %s" msgid "Unable to retrieve share_type." msgstr "Не удалось получить тип общего ресурса" msgid "Unable to retrieve snapshot details." msgstr "Не удалось получить детали снимка." msgid "Unable to retrieve snapshot." msgstr "Не удалось получить снимок." msgid "Unable to retrieve volume details." msgstr "Не удалось получить информацию о диске." #, python-format msgid "Unable to set replica '%s' as active." msgstr "Невозможно назначить реплику '%s' активной." msgid "Unable to unmanage share." msgstr "Невозможно разрегистрировать общий ресурс." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Невозможно обновить доступ к типу общего ресурса \"%s\"." msgid "Unable to update default quotas." msgstr "Не удалось обновить квоты по умолчанию." msgid "Unable to update security service." msgstr "Невозможно обновить службу безопасности." msgid "Unable to update share metadata." msgstr "Невозможно обновить метаданные общего ресурса." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Невозможно обновить сеть общего ресурса \"%s\"." msgid "Unable to update share network." msgstr "Невозможно обновить сеть общего ресурса." msgid "Unable to update share type." msgstr "Невозможно обновить тип общего ресурса." msgid "Unable to update share." msgstr "Не удалось обновить общий ресурс." msgid "Unknown" msgstr "Неизвестно" msgid "Unmanage" msgstr "Разрегистрировать" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Ошибка регистрации общего ресурса" msgid "Unmanage Share" msgstr "Разрегистрировать общий ресурс" msgid "Update" msgstr "Обновить" msgid "Update Share Network" msgstr "Обновить сеть общего ресурса" msgid "Update Share Type" msgstr "Обновить тип общего ресурса" msgid "Updated At" msgstr "Обновлено" #, python-format msgid "Updated access for share type \"%s\"." msgstr "Доступ для типа общего ресурса \"%s\" обновлен." #, python-format msgid "Updated share network \"%s\"." msgstr "Сеть общего ресурса \"%s\" обновлена" #, python-format msgid "Updating share \"%s\"" msgstr "Обновление общего ресурса \"%s\"" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Обновление метаданных общего ресурса \"%s\"" #, python-format msgid "Updating share network \"%s\"" msgstr "Обновление сети общего ресурса \"%s\"" msgid "Use snapshot as a source" msgstr "Использовать снимок как источник" msgid "User" msgstr "Пользователь" msgid "Visibility" msgstr "Видимость" msgid "Writable" msgstr "Записываемый" msgid "key=value pairs per line can be set" msgstr "Пара значений key=value может быть задана для каждой строки" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7786515 manila-ui-11.0.0/manila_ui/locale/tr_TR/0000775000175000017500000000000000000000000017717 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/locale/tr_TR/LC_MESSAGES/0000775000175000017500000000000000000000000021504 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/locale/tr_TR/LC_MESSAGES/django.po0000664000175000017500000011513600000000000023315 0ustar00zuulzuul00000000000000# işbaran akçayır , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-03-06 13:24+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-08-25 07:29+0000\n" "Last-Translator: Copied by Zanata \n" "Language-Team: Turkish (Turkey)\n" "Language: tr_TR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Zanata 4.3.3\n" "X-POOTLE-MTIME: 1495463317.000000\n" #, python-format msgid "%sGiB" msgstr "%sGiB" msgid "(Quota exceeded)" msgstr "(Kota aşıldı)" msgid "Access Key" msgstr "Erişim Anahtarı" msgid "Access Level" msgstr "Erişim Seviyesi" msgid "Access To" msgstr "Erişim" msgid "Access Type" msgstr "Erişim Türü" msgid "Access to" msgstr "Erişim" msgctxt "Current status of share network" msgid "Active" msgstr "Etkin" msgctxt "Current status of share server" msgid "Active" msgstr "Etkin" msgid "Add" msgstr "Ekle" msgid "Add Rule" msgstr "Kural Ekle" msgid "Add Security Service" msgstr "Güvenlik Servisi Ekle" msgid "Add Share Snapshot Rule" msgstr "Paylaşım Anlık Görüntü Kuralı Ekle" msgid "Add rule" msgstr "Kural ekle" msgid "Add security services to share network." msgstr "Paylaşım ağına güvenlik servisleri ekle." msgid "All keys and values must be in range from 1 to 255." msgstr "Tüm anahtarlar ve değerler 1 ve 255 aralığında olmalı." msgid "Allow project access to share group type." msgstr "Paylaşım grubu türüne proje erişimine izin ver." msgid "Allow project access to share type." msgstr "Paylaşım türüne proje erişimi ver." msgid "At least one security service must be specified." msgstr "En az bir güvenlik servisi belirtilmeli." msgid "At least one share type must be specified." msgstr "En az bir paylaşım türü belirtilmelidir." msgid "Availability Zone" msgstr "Kullanılırlık Bölgesi" msgid "Availability zone" msgstr "Kullanılırlık bölgesi" msgctxt "Current status of replica" msgid "Available" msgstr "Kullanılabilir" msgctxt "Current status of share" msgid "Available" msgstr "Kullanılabilir" msgctxt "Current status of snapshot" msgid "Available" msgstr "Uygun" msgid "Available projects" msgstr "Kullanılabilir projeler" msgid "Available security services" msgstr "Kullanılabilir güvenlik servisleri" msgid "Cancel Migration" msgstr "Göçü İptal Et" msgid "Cancel migration" msgstr "Göçü iptal et" msgid "Cancel migration of a Share" msgstr "Bir Paylaşımın göçünü iptal et" msgid "Choose a snapshot" msgstr "Bir anlık görüntü seçin" msgid "Complete Migration" msgstr "Göçü Tamamla" msgid "Complete migration" msgstr "Göçü tamamla" msgid "Complete migration of a Share" msgstr "Bir paylaşımın göçünü tamamla" msgid "Confirm Migration Cancelling of Share" msgstr "Paylaşım Göç İptalini Onayla" msgid "Confirm Migration Completion of Share" msgstr "Paylaşımın Göç Tamamlanmasını Onayla" msgid "Confirm Obtaining migration progress of Share" msgstr "Paylaşım göç sürecini Almayı onayla" msgid "Confirm Password" msgstr "Parolayı Onayla" msgid "Confirm Unmanage Share" msgstr "Paylaşım Yönetim İptalini Onayla" msgid "Create" msgstr "Oluştur" msgid "Create Replica" msgstr "Kopya Oluştur" msgid "Create Security Service" msgstr "Güvenlik Servisi Oluştur" msgid "Create Share" msgstr "Paylaşım Oluştur" msgid "Create Share Group" msgstr "Paylaşım Grubu Oluştur" msgid "Create Share Group Snapshot" msgstr "Paylaşım Grubu Anlık Görüntüsü Oluştur" msgid "Create Share Group Type" msgstr "Paylaşım Grubu Türü Oluştur" msgid "Create Share Network" msgstr "Paylaşım Ağı Oluştur" msgid "Create Share Snapshot" msgstr "Paylaşım Anlık Görüntüsü Oluştur" msgid "Create Share Type" msgstr "Paylaşım Türü Oluştur" msgid "Create a Share" msgstr "Bir Paylaşım Oluştur" msgid "Created At" msgstr "Oluşturulma Tarihi" msgid "Created at" msgstr "Oluşturulma" msgctxt "Current status of replica" msgid "Creating" msgstr "Oluşturuluyor" msgctxt "Current status of share" msgid "Creating" msgstr "Oluşturuluyor" msgctxt "Current status of share server" msgid "Creating" msgstr "Oluşturuluyor" msgctxt "Current status of snapshot" msgid "Creating" msgstr "Oluşturuluyor" #, python-format msgid "Creating replica for share \"%s\"." msgstr "\"%s\" paylaşımı için kopya oluşturuluyor." #, python-format msgid "Creating rule for \"%s\"" msgstr "\"%s\" için kural oluşturuluyor" #, python-format msgid "Creating share \"%s\"" msgstr "\"%s\" paylaşımı oluşturuluyor" #, python-format msgid "Creating share group \"%s\"" msgstr "\"%s\" paylaşım grubu oluşturuluyor" #, python-format msgid "Creating share group snapshot \"%s\"." msgstr "Paylaşım grubu anlık görüntüsü \"%s\" oluşturuluyor." #, python-format msgid "Creating share snapshot \"%s\"." msgstr "Paylaşım anlık görüntüsü \"%s\"." #, python-format msgid "Creating snapshot rule for \"%s\"" msgstr "\"%s\" için anlık görüntü kuralı oluşturuluyor" msgid "Current Size (GiB)" msgstr "Mevcut Boyut (GiB)" msgid "DNS IP" msgstr "DNS IP" msgid "Delete Replica" msgid_plural "Delete Replicas" msgstr[0] "Kopyayı Sil" msgstr[1] "Kopyaları Sil" msgid "Delete Rule" msgid_plural "Delete Rules" msgstr[0] "Kuralı Sil" msgstr[1] "Kuralları Sil" msgid "Delete Security Service" msgid_plural "Delete Security Services" msgstr[0] "Güvenlik Servisini Sil" msgstr[1] "Güvenlik Servislerini Sil" msgid "Delete Share" msgid_plural "Delete Shares" msgstr[0] "Paylaşımı Sil" msgstr[1] "Paylaşımları Sil" msgid "Delete Share Group" msgid_plural "Delete Share Groups" msgstr[0] "Paylaşım Grubunu Sil" msgstr[1] "Paylaşım Gruplarını Sil" msgid "Delete Share Group Snapshot" msgid_plural "Delete Share Group Snapshots" msgstr[0] "Paylaşım Grubu Anlık Görüntüsünü Sil" msgstr[1] "Paylaşım Grubu Anlık Görüntülerini Sil" msgid "Delete Share Group Type" msgid_plural "Delete Share Group Types" msgstr[0] "Paylaşım Grubu Türünü Sil" msgstr[1] "Paylaşım Grubu Türlerini Sil" msgid "Delete Share Network" msgid_plural "Delete Share Networks" msgstr[0] "Paylaşım Ağını Sil" msgstr[1] "Paylaşım Ağlarını Sil" msgid "Delete Share Server" msgid_plural "Delete Share Server" msgstr[0] "Paylaşım Sunucusu Sil" msgstr[1] "Paylaşım Sunucularını Sil" msgid "Delete Share Snapshot" msgid_plural "Delete Share Snapshots" msgstr[0] "Paylaşım Anlık Görüntüsünü Sİl" msgstr[1] "Paylaşım Anlık Görüntülerini Sİl" msgid "Delete Share Snapshot Rule" msgid_plural "Delete Share Snapshot Rules" msgstr[0] "Paylaşım Anlık Görüntü Kuralı Sil" msgstr[1] "Paylaşım Anlık Görüntü Kurallarını Sil" msgid "Delete Share Type" msgid_plural "Delete Share Types" msgstr[0] "Paylaşım Türünü Sil" msgstr[1] "Paylaşım Türlerini Sil" msgid "Delete Snapshot" msgid_plural "Delete Snapshots" msgstr[0] "Anlık Görüntü Sil" msgstr[1] "Anlık Görüntüleri Sil" msgid "Deleted Replica" msgid_plural "Deleted Replicas" msgstr[0] "Kopya Silindi" msgstr[1] "Kopyalar Silindi" msgid "Deleted Rule" msgid_plural "Deleted Rules" msgstr[0] "Kural Silindi" msgstr[1] "Kurallar Silindi" msgid "Deleted Security Service" msgid_plural "Deleted Security Services" msgstr[0] "Güvenlik Servisi Silindi" msgstr[1] "Güvenlik Servisleri Silindi" msgid "Deleted Share" msgid_plural "Deleted Shares" msgstr[0] "Paylaşım Silindi" msgstr[1] "Paylaşımlar Silindi" msgid "Deleted Share Group" msgid_plural "Deleted Share Groups" msgstr[0] "Paylaşım Grubunu Sil" msgstr[1] "Paylaşım Gruplarını Sil" msgid "Deleted Share Group Snapshot" msgid_plural "Deleted Share Group Snapshots" msgstr[0] "Paylaşım Grubu Anlık Görüntüsünü Sil" msgstr[1] "Paylaşım Grubu Anlık Görüntülerini Sil" msgid "Deleted Share Group Type" msgid_plural "Deleted Share Group Types" msgstr[0] "Paylaşım Grubu Türünü Sil" msgstr[1] "Paylaşım Grubu Türlerini Sil" msgid "Deleted Share Network" msgid_plural "Deleted Share Networks" msgstr[0] "Paylaşım Ağı Silindi" msgstr[1] "Paylaşım Ağları Silindi" msgid "Deleted Share Server" msgid_plural "Deleted Share Server" msgstr[0] "Paylaşım Sunucusu Silindi" msgstr[1] "Paylaşım Sunucuları Silindi" msgid "Deleted Share Snapshot" msgid_plural "Deleted Share Snapshots" msgstr[0] "Paylaşım Anlık Görüntüsünü Sil" msgstr[1] "Paylaşım Anlık Görüntülerini Sil" msgid "Deleted Share Snapshot Rule" msgid_plural "Deleted Share Snapshot Rules" msgstr[0] "Paylaşım Anlık Görüntü Kuralı Sil" msgstr[1] "Paylaşım Anlık Görüntü Kurallarını Sil" msgid "Deleted Share Type" msgid_plural "Deleted Share Types" msgstr[0] "Paylaşım Türü Silindi" msgstr[1] "Paylaşım Türleri Silindi" msgid "Deleted Snapshot" msgid_plural "Deleted Snapshots" msgstr[0] "Anlık Görüntü Silindi" msgstr[1] "Anlık Görüntüler Silindi" msgctxt "Current status of replica" msgid "Deleting" msgstr "Siliniyor" msgctxt "Current status of share" msgid "Deleting" msgstr "Siliniyor" msgid "Description" msgstr "Açıklama" msgid "Destination host and pool where share will be migrated to." msgstr "Paylaşımın geçirileceği hedef istemci ve havuz." msgid "Domain" msgstr "Alan" msgid "Driver handles share servers" msgstr "Sürücü paylaşım sunucuları ele alır" msgid "Driver options ('volume_id' for Generic driver, etc...)" msgstr "Sürücü seçenekleri (Genel sürücü için 'birim_kimliği', vs...)" #, python-format msgid "Duplicated keys '%s'." msgstr "Kopya anahtarlar '%s'." msgid "Edit" msgstr "Düzenle" msgid "Edit Security Service" msgstr "Güvenlik Servisini Düzenle" msgid "Edit Share" msgstr "Paylaşımı Düzenle" msgid "Edit Share Metadata" msgstr "Paylaşım Metaverisini Düzenle" msgid "Edit Share Network" msgstr "Paylaşım Ağını Düzenle" msgid "Edit Share Snapshot" msgstr "Paylaşım Anlık Görüntüsü Düzenle" msgid "" "Enforces migration of the share snapshots to the destination. If set to " "True, host-assisted migration will not be attempted." msgstr "" "Paylaşım anlık görüntülerinin hedefe göçünü zorlar. Doğru olarak " "işaretlenirse, istemci-destekli göç denenmez." msgid "" "Enforces migration to be nondisruptive. If set to True, host-assisted " "migration will not be attempted." msgstr "" "Göçün aksatmadan yapılmasına zorlar. Doğru olarak ayarlanırsa, istemci-" "destekli göç denenmez." msgid "" "Enforces migration to keep the share writable while contents are being " "moved. If set to True, host-assisted migration will not be attempted." msgstr "" "Göç sırasında içerik taşınırken paylaşımın yazılabilir kalmasını zorlar. " "Doğru olarak ayarlanırsa, istemci-destekli göç denenmez." msgid "" "Enforces migration to preserve all file metadata when moving its contents. " "If set to True, host-assisted migration will not be attempted." msgstr "" "Göç sırasında içeriği taşırken tüm metaveri dosyasının korunmasını zorlar. " "Doğru olarak işaretlenirse, istemci-destekli göç denenmez." msgid "" "Enforces the use of the host-assisted migration approach, which bypasses " "driver optimizations." msgstr "" "İstemci-destekli göç yaklaşımını kullanmaya zorlar, sürücü iyileştirmeleri " "atlanır." msgctxt "Current status of replica" msgid "Error" msgstr "Hata" msgctxt "Current status of share" msgid "Error" msgstr "Hata" msgctxt "Current status of share network" msgid "Error" msgstr "Hata" msgctxt "Current status of share server" msgid "Error" msgstr "Hata" msgctxt "Current status of snapshot" msgid "Error" msgstr "Hata" msgid "Expected only pairs of key=value." msgstr "Yalnızca anahtar=değer çiftleri bekleniyor." msgid "Export location" msgstr "Dışa aktarım konumu" msgid "Export location of share. Example for NFS: 1.2.3.4:/path/to/share" msgstr "" "Paylaşımın dışa aktarım konumu. Örneğin NFS için 1.2.3.4:/paylaşım/yolu" msgctxt "Current status of share" msgid "Extending Error" msgstr "Genişletme Hatası" msgid "Extra specs" msgstr "Ek özellikler" msgid "Force Host Assisted Migration" msgstr "İstemci Destekli Göçe Zorla" msgid "From here you can update share network info. " msgstr "Burdan paylaşım ağı bilgisini güncelleyebilirsiniz. " msgid "Get migration progress" msgstr "Göç ilerlemesini al" msgid "" "Got improper value for field 'driver_options'. Expected only pairs of " "key=value." msgstr "" "'driver_options' alanı için geçersiz değer alındı. Yalnızca anahtar=değer " "çiftleri bekleniyor." msgid "Group specs" msgstr "Grup özellikleri" msgid "Host" msgstr "Sunucu" msgid "Host of share" msgstr "Paylaşım sunucusu" msgid "Host to migrate share" msgstr "Paylaşımın geçirileceği istemci" msgid "Host where share is located, example: some.host@driver[#pool]" msgstr "Paylaşımın konumlandığı sunucu, örneğin: bir.sunucu@sürücü[#havuz]" msgid "ID" msgstr "ID" msgid "IP Version" msgstr "IP Sürümü" msgid "Id" msgstr "Id" #, python-format msgid "" "Improper value set to required extra spec " "'spec_driver_handles_share_servers'. Allowed values are %s. Case insensitive." msgstr "" "'spec_driver_handles_share_servers' ek özelliği için uygun olmayan değer " "ayarlanmış. İzin verilen değerler %s. Büyük küçük harfe duyarsız." msgctxt "Current status of share server" msgid "In-use" msgstr "Kullanımda" msgctxt "Current status of snapshot" msgid "In-use" msgstr "Kullanımda" msgctxt "Current status of share network" msgid "Inactive" msgstr "Pasif" #, python-format msgid "Key '%s' has improper length." msgstr "Anahtar '%s' uygunsuz uzunluğa sahip." #, python-format msgid "Key can not contain spaces. See string '%s'." msgstr "Anahtar boşluk içeremez. '%s' karakter dizisine göz atın." #, python-format msgid "Keys should not contain spaces. Error in '%s'." msgstr "Anahtarlar boşluk içermemeli. '%s'de hata." msgid "Manage" msgstr "Yönet" msgctxt "Current status of share" msgid "Manage Error" msgstr "Yönetme Hatası" msgid "Manage Replicas" msgstr "Kopyaları Yönet" msgid "Manage Rules" msgstr "Kuralları Yönet" msgid "Manage Share" msgstr "Paylaşımı Yönet" msgid "Manage Share Group Type Access" msgstr "Paylaşım Grubu Türü Erişimini Yönet" msgid "Manage Share Snapshot Rules" msgstr "Paylaşım Anlık Görüntü Kurallarını Yönet" msgid "Manage Share Type Access" msgstr "Paylaşım Türü Erişimini Yönet" msgid "Metadata" msgstr "Metaveri" msgid "Migrate Share" msgstr "Paylaşımı Göç Ettir" msgid "Migrate a Share" msgstr "Bir paylaşımı göç ettir" msgctxt "Current status of share" msgid "Migrating" msgstr "Göç Ediyor" msgctxt "Current status of share" msgid "Migrating to" msgstr "Göç konumu" #, python-format msgid "Migration of share %(name)s is at %(progress)s percent." msgstr "%(name)s paylaşımının göçü yüzde %(progress)s." msgid "Name" msgstr "İsim" msgid "Network Type" msgstr "Ağ Türü" msgid "Networks" msgstr "Ağlar" msgid "Neutron Net" msgstr "Neutron Ağı" msgid "Neutron Subnet" msgstr "Neutron Alt Ağı" msgid "New Size (GiB)" msgstr "Yeni Boyut (GiB)" msgid "New share network to be set in migrated share" msgstr "Göç etmiş paylaşımda yeni paylaşım ağı ayarlanacak" msgid "New share type to be set in migrating share" msgstr "Göç eden paylaşımda ayarlanacak yeni paylaşım türü" msgid "No projects found." msgstr "Proje bulunamadı." msgid "No projects selected." msgstr "Hiçbir proje seçili değil." msgid "No security services found." msgstr "Hiçbir güvenlik servisi bulunamadı." msgid "No security services selected." msgstr "Hiçbir güvenlik servisi seçilmemiş." msgid "No source, empty share" msgstr "Kaynak yok, boş paylaşım" msgid "No source, empty share group" msgstr "Kaynak yok, boş paylaşım grubu" msgid "Nondisruptive" msgstr "Aksatmadan" msgid "Obtain Progress" msgstr "Süreci Al" msgid "Obtain migration progress of a Share" msgstr "Bir Paylaşımın göç sürecini al" msgid "Overview" msgstr "Genel Görünüm" msgid "Password" msgstr "Parola" msgid "Passwords do not match." msgstr "Parolalar eşleşmiyor." msgid "Preserve Metadata" msgstr "Metaveriyi Koru" msgid "Preserve Snapshots" msgstr "Anlık Görüntüleri Koru" msgid "Project" msgstr "Proje" msgid "Projects with access to share group type" msgstr "Paylaşım grubu türüne erişimi olan projeler" msgid "Projects with access to share type" msgstr "Paylaşım türüne erişimi olan projeler" msgid "Protocol" msgstr "İletişim Kuralı" msgid "Public" msgstr "Açık" #, python-format msgid "Replica Details: %(replica_display_name)s" msgstr "Kopya Ayrıntıları: %(replica_display_name)s" msgid "Replica State" msgstr "Kopya Durumu" msgid "Replicas" msgstr "Kopyalar" msgid "Reset Replica State" msgstr "Kopya Durumunu Sıfırla" msgid "Reset Replica Status" msgstr "Kopya Durumunu Sıfırla" msgid "Reset Share Group Snapshot Status" msgstr "Paylaşım Grubu Anlık Görüntü Durumu" msgid "Reset Share Group Status" msgstr "Paylaşım Grubu Durumunu Sıfırla" msgid "Reset Status" msgstr "Durumu Sıfırla" msgid "Reset replica state" msgstr "Kopya durumunu sıfırla" msgid "Reset replica status" msgstr "Kopya durumunu sıfırla" msgid "Reset state" msgstr "Durumu sıfırla" msgid "Reset status" msgstr "Durumu sıfırla" #, python-format msgid "Reseting replica ('%(id)s') state from '%(from)s' to '%(to)s'." msgstr "Kopya ('%(id)s') durumu '%(from)s' den '%(to)s' e sıfırlanıyor." #, python-format msgid "Reseting replica ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "Kopya ('%(id)s') durumu '%(from)s' den '%(to)s' e yeniden ayarlanıyor." #, python-format msgid "Reseting share group ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "('%(id)s') paylaşım grubu durumu '%(from)s' den '%(to)s' e sıfırlanıyor." #, python-format msgid "" "Reseting share group snapshot ('%(id)s') status from '%(from)s' to '%(to)s'." msgstr "" "Paylaşım grubu anlık görüntüsü ('%(id)s') durumu '%(from)s' den '%(to)s' e " "yeniden ayarlanıyor." msgid "Resync" msgstr "Yeniden eşzamanla" msgid "Resync Replica" msgstr "Kopyayı Yeniden Eşzamanla" msgid "Resync replica" msgstr "Kopyayı yeniden eş zamanla" #, python-format msgid "Resync'ing replica '%s'" msgstr "Kopya '%s' yeniden eş zamanlanıyor" msgid "Revert Share" msgstr "Paylaşımı Geri Döndür" msgid "Revert Share to a Snapshot" msgstr "Paylaşımı Anlık Görüntüye Geri Al" msgid "Revert share to a snapshot" msgstr "Paylaşımı bir anlık görüntüye geri al" msgctxt "Current status of share" msgid "Reverting Error" msgstr "Geri Alma Hatası" msgid "Rules" msgstr "Kurallar" msgid "Save Changes" msgstr "Değişiklikleri Kaydet" #, python-format msgid "Security Service Details: %(service_display_name)s" msgstr "Güvenlik Servisi Ayrıntıları: %(service_display_name)s" msgid "Security Service Overview" msgstr "Güvenlik Servisi Genel Görünümü" msgid "Security Services" msgstr "Güvenlik Servisleri" msgid "Security services within share network" msgstr "Paylaşım ağındaki güvenlik servisleri" msgid "Segmentation Id" msgstr "Dilimlendirme Kimliği" msgid "Selected projects" msgstr "Seçili projeler" msgid "Selected security services" msgstr "Seçili güvenlik servisleri" msgid "Server" msgstr "Sunucu" msgid "Set Replica as Active" msgstr "Kopyayı Etkin olarak Ayarla" msgid "Set as Active" msgstr "Etkin olarak Ayarla" msgid "Set maximum quotas for the project." msgstr "Proje için azami kotaları ayarla." #, python-format msgid "Setting replica \"%s\" as active..." msgstr "\"%s\" kopyası etkin olarak ayarlanıyor..." #, python-format msgid "Share \"%(s)s\" has been reverted to \"%(ss)s\" snapshot successfully" msgstr "Paylaşım \"%(s)s\" \"%(ss)s\" anlık görüntüsüne başarıyla geri alındı" #, python-format msgid "Share Details: %(share_display_name)s" msgstr "Paylaşım Ayrıntıları: %(share_display_name)s" #, python-format msgid "Share Details: %(share_name)s" msgstr "Paylaşım Ayrıntıları: %(share_name)s" msgid "Share Group" msgstr "Paylaşım Grubu" #, python-format msgid "Share Group Details: %s" msgstr "Paylaşım Grubu Ayrıntıları: %s" msgid "Share Group Name" msgstr "Paylaşım Grubu İsmi" msgid "Share Group Overview" msgstr "Paylaşım Grubu Genel Görünümü" msgid "Share Group Snapshot" msgstr "Paylaşım Grubu Anlık Görüntüsü" #, python-format msgid "Share Group Snapshot Details: %(sgs_display_name)s" msgstr "Paylaşım Grubu Anlık Görüntü Ayrıntıları: %(sgs_display_name)s" msgid "Share Group Snapshot Overview" msgstr "Paylaşım Grubu Anlık Görüntüsü Genel Görünümü" msgid "Share Group Snapshots" msgstr "Paylaşım Grubu Anlık Görüntüleri" msgid "Share Group Type" msgstr "Paylaşım Grubu Türü" msgid "Share Group Types" msgstr "Paylaşım Grubu Türleri" msgid "Share Groups" msgstr "Paylaşım Grupları" msgid "Share ID" msgstr "Paylaşım Kimliği" #, python-format msgid "Share Instance Details: %s" msgstr "Paylaşım Sunucusu Ayrıntıları: %s" msgid "Share Instance Overview" msgstr "Paylaşım Sunucusu Genel Görünümü" msgid "Share Instances" msgstr "Paylaşım Sunucuları" msgid "Share Name" msgstr "Paylaşım İsmi" msgid "Share Network" msgstr "Paylaşım Ağı" #, python-format msgid "Share Network Details: %(network_display_name)s" msgstr "Paylaşım Ağı Ayrıntıları: %(network_display_name)s" msgid "Share Network Info" msgstr "Paylaşım Ağı Bilgisi" msgid "Share Network Overview" msgstr "Paylaşım Ağı Genel Görünümü" msgid "Share Networks" msgstr "Paylaşım Ağları" msgid "Share Overview" msgstr "Paylaşım Genel Görünümü" msgid "Share Protocol" msgstr "Paylaşım Protokolü" #, python-format msgid "Share Replicas: %(share_display_name)s" msgstr "Paylaşım Kopyaları: %(share_display_name)s" #, python-format msgid "Share Rules: %(share_display_name)s" msgstr "Paylaşım Kuralları: %(share_display_name)s" msgid "Share Server" msgstr "Paylaşım Sunucu" #, python-format msgid "Share Server Details: %(server_name)s" msgstr "Paylaşım Sunucusu Ayrıntıları: %(server_name)s" msgid "Share Server Id" msgstr "Paylaşım Sunucu Kimliği" msgid "Share Server Overview" msgstr "Paylaşım Sunucusu Genel Görünümü" msgid "Share Servers" msgstr "Paylaşım Sunucuları" msgid "Share Snapshot Name" msgstr "Paylaşım Anlık Görüntü İsmi" msgid "Share Snapshot Overview" msgstr "Paylaşım Anlık Görüntüsü Genel Görünümü" msgid "Share Snapshot Rules" msgstr "Paylaşım Anlık Görüntü Kuralları" msgid "Share Snapshots" msgstr "Paylaşım Anlık Görüntüleri" msgid "Share Snapshots Storage" msgstr "Paylaşım Anlık Görüntüleri Depolama" msgid "Share Source" msgstr "Paylaşım Kaynağı" msgid "Share Storage" msgstr "Paylaşım Depolama" msgid "Share Type" msgstr "Paylaşım Türü" msgid "Share Types" msgstr "Paylaşım Türleri" msgid "Share Types (multiple available)" msgstr "Paylaşım Türleri (birden çok kullanılabilir)" msgid "Share Types (one available)" msgstr "Paylaşım Türleri (biri kullanılabilir)" #, python-format msgid "" "Share cannot be extended to %(req)iGiB as you only have %(avail)iGiB of your " "quota available." msgstr "" "Kotanızda yalnız %(avail)iGiB olduğundan paylaşım %(req)iGiB olarak " "büyütülemedi." msgid "Share gigabytes" msgstr "Paylaşım gigabayt" msgid "Share name to be assigned" msgstr "Atanacak paylaşım adı" #, python-format msgid "Share replica %s has been deleted." msgstr "Paylaşım kopyası %s silindi." #, python-format msgid "Share size must be equal to or greater than the snapshot size (%sGiB)" msgstr "" "Paylaşım boyutu anlık görüntü boyutuna eşit ya da boyutundan fazla olmalı " "(%sGiB)" msgid "Share snapshot gigabytes" msgstr "Paylaşım anlık görüntü gigabaytları" msgid "Share snapshots" msgstr "Paylaşım anlık görüntüleri" msgid "Share types" msgstr "Paylaşım türleri" msgid "Shares" msgstr "Paylaşımlar" msgid "Sid" msgstr "Sid" msgid "Size" msgstr "Boyut" msgid "Size (GiB)" msgstr "Boyut (GiB)" msgid "Snapshot" msgstr "Anlık görüntü" #, python-format msgid "Snapshot Details: %(snapshot_display_name)s" msgstr "Anlık Görüntü Ayrıntıları: %(snapshot_display_name)s" msgid "Snapshot Overview" msgstr "Anlık Görüntü Genel Görünümü" #, python-format msgid "Snapshot Rules: %(snapshot_display_name)s" msgstr "Anlık Görüntü Kuralları: %(snapshot_display_name)s" msgid "Source" msgstr "Kaynak" msgid "Source Share Group Snapshot" msgstr "Paylaşım Grubu Anlık Görüntüsünü Kaynak Et" msgid "Source Type" msgstr "Kaynak Türü" msgid "" "Specify the new share network for the share. Do not specify this parameter " "if the migrating share has to be retained within its current share network." msgstr "" "Paylaşım için yeni paylaşım ağını belirtin. Göç eden paylaşımın mevcut " "paylaşım ağını koruması gerekiyorsa bu parametreyi belirtmeyin." msgid "" "Specify the new share type for the share. Do not specify this parameter if " "the migrating share has to be retained with its current share type." msgstr "" "Paylaşım için yeni paylaşım türünü belirtin. Göç eden paylaşımın mevcut " "paylaşım türünü koruması gerekiyorsa bu parametreyi belirtmeyin." msgid "Start migration" msgstr "Göçü başlat" msgid "Status" msgstr "Durum" #, python-format msgid "Successfully created security service: %s" msgstr "Güvenlik servisi başarıyla oluşturuldu: %s" #, python-format msgid "Successfully created share group type: %s" msgstr "Başarıyla paylaşım grubu türü oluşturuldu: %s" #, python-format msgid "Successfully created share network: %s" msgstr "Paylaşım ağı başarıyla oluşturuldu: %s" #, python-format msgid "Successfully created share type: %s" msgstr "Paylaşım türü başarıyla oluşturuldu: %s" #, python-format msgid "Successfully sent the request to cancel migration of share: %s." msgstr "Paylaşımın göç iptali için istek başarıyla gönderildi: %s." #, python-format msgid "Successfully sent the request to complete migration of share: %s." msgstr "Paylaşım göçünün tamamlanması isteği başarıyla gönderildi: %s." #, python-format msgid "Successfully sent the request to manage share: %s" msgstr "Paylaşımı yönetme isteği başarıyla gönderildi: %s" #, python-format msgid "Successfully sent the request to migrate share: %s." msgstr "İstek göç paylaşımına başarıyla gönderildi: %s." #, python-format msgid "Successfully sent the request to unmanage share: %s" msgstr "Paylaşımın yönetim iptali isteği başarıyla gönderildi: %s" #, python-format msgid "Successfully updated group specs for share group type '%s'." msgstr "'%s' paylaşım grubu türü için grup özellikleri başarıyla güncellendi." #, python-format msgid "Successfully updated security service \"%s\"" msgstr "Güvenlik servisi \"%s\" başarıyla güncellendi" #, python-format msgid "The share size cannot be less than the snapshot size (%sGiB)" msgstr "Paylaşım boyutu anlık görüntü boyutundan az olamaz (%sGiB)" msgid "Type" msgstr "Tür" msgid "Unable to add rule." msgstr "Kural eklenemedi." msgid "Unable to add snapshot rule." msgstr "Anlık görüntü kuralı eklenemedi." #, python-format msgid "Unable to cancel migration of share %s at this moment." msgstr "%s paylaşımının göçü şu an iptal edilemiyor." #, python-format msgid "Unable to complete migration of share %s." msgstr "%s paylaşımının göçü tamamlanamadı." msgid "Unable to create security service." msgstr "Güvenlik servisi oluşturulamıyor." msgid "Unable to create share group snapshot." msgstr "Paylaşım grubu anlık görüntüsü oluşturulamadı." msgid "Unable to create share group type." msgstr "Paylaşım grubu türü oluşturulamadı." msgid "Unable to create share group." msgstr "Paylaşım grubu oluşturulamıyor." msgid "Unable to create share network." msgstr "Paylaşım ağı oluşturulamadı." msgid "Unable to create share replica." msgstr "Paylaşım kopyası oluşturulamadı." msgid "Unable to create share snapshot." msgstr "Paylaşım anlık görüntüsü oluşturulamıyor." msgid "Unable to create share type." msgstr "Paylaşım türü oluşturulamıyor." msgid "Unable to create share." msgstr "Paylaşım oluşturulamadı." #, python-format msgid "Unable to create share. %s" msgstr "Paylaşım oluşturulamadı. %s" #, python-format msgid "Unable to delete replica \"%s\"." msgstr "Kopya \"%s\" silinemedi." #, python-format msgid "Unable to delete rule \"%s\"." msgstr "\"%s\" kuralı silinemedi." #, python-format msgid "Unable to delete share \"%s\". " msgstr "\"%s\" paylaşımı silinemedi. " #, python-format msgid "" "Unable to delete share group snapshot \"%s\". One or more share groups " "depend on it." msgstr "" "\"%s\" paylaşım grubu anlık görüntüsü silinemiyor. Bir ya da daha fazla " "paylaşım grubu ona bağımlı." #, python-format msgid "Unable to delete snapshot \"%s\". One or more shares depend on it." msgstr "" "\"%s\" anlık görüntüsü silinemedi. Bir ya da fazla paylaşım ona bağımlı." #, python-format msgid "Unable to delete snapshot rule \"%s\"." msgstr "Anlık görüntü kuralı \"%s\" silinemiyor." msgid "Unable to get information about share group type access." msgstr "Paylaşım grubu tür erişimiyle ilgili bilgi alınamadı." msgid "Unable to get information about share type access." msgstr "Paylaşım türü erişimi hakkında bilgi alınamadı." msgid "Unable to get list of projects." msgstr "Proje listesi alınamadı." msgid "Unable to get the security services hosts" msgstr "Güvenlik servisi sunucuları alınamadı" #, python-format msgid "Unable to get the specified share group '%s' for snapshot creation." msgstr "" "Anlık görüntü oluşturmak için belirtilen paylaşım grubu '%s' alınamadı." msgid "Unable to load the specified share group snapshot." msgstr "Belirtilen paylaşım grubu anlık görüntüsü yüklenemedi." msgid "Unable to load the specified snapshot." msgstr "Belirtilen anlık görüntü yüklenemedi." msgid "Unable to manage share" msgstr "Paylaşım yönetilemiyor" #, python-format msgid "Unable to migrate share %s." msgstr "%s paylaşımı göç ettirilemedi." #, python-format msgid "Unable to obtain progress of migration of share %s at this moment." msgstr "%s paylaşımının göç yüzdesi şu an alınamıyor." #, python-format msgid "Unable to reset state of replica '%s'." msgstr "'%s' kopyasının durumu sıfırlanamadı." #, python-format msgid "Unable to reset status of replica '%s'." msgstr "'%s' kopyasının durumu sıfırlanamadı." #, python-format msgid "Unable to reset status of share group '%s'." msgstr "'%s' paylaşım grubu durumu sıfırlanamadı." #, python-format msgid "Unable to reset status of share group snapshot '%s'." msgstr "'%s' paylaşım grubu anlık görüntüsü durumu sıfırlanamıyor." #, python-format msgid "Unable to resync replica '%s'." msgstr "Kopya '%s' yeniden eş zamanlanamadı." msgid "Unable to retrieve list of projects." msgstr "Projelerin listesi alınamadı." msgid "Unable to retrieve quotas." msgstr "Kotalar alınamıyor." #, python-format msgid "Unable to retrieve replica '%s'." msgstr "Kopya '%s' alınamadı." #, python-format msgid "Unable to retrieve security service '%s' details." msgstr "Güvenlik servisi '%s' ayrıntıları alınamıyor." msgid "Unable to retrieve security services" msgstr "Güvenlik servisleri alınamadı" msgid "Unable to retrieve security_service." msgstr "security_service alınamadı." msgid "Unable to retrieve share details." msgstr "Paylaşım ayrıntıları alınamadı." #, python-format msgid "Unable to retrieve share group '%s'." msgstr "Paylaşım grubu '%s' alınamıyor." msgid "Unable to retrieve share group details." msgstr "Paylaşım grubu ayrıntıları alınamıyor." #, python-format msgid "Unable to retrieve share group snapshot '%s'." msgstr "Paylaşım grubu anlık görüntüsü '%s' alınamıyor." msgid "Unable to retrieve share group snapshot details." msgstr "Paylaşım grubu anlık görüntü ayrıntıları alınamıyor." msgid "Unable to retrieve share group snapshot list." msgstr "Paylaşım grubu anlık görüntü listesi alınamıyor." msgid "Unable to retrieve share group snapshot." msgstr "Paylaşım grubu anlık görüntüsü alınamıyor." msgid "Unable to retrieve share group snapshots." msgstr "Paylaşım grubu anlık görüntüleri alınamadı." msgid "Unable to retrieve share group types." msgstr "Paylaşım grubu türleri alınamadı." msgid "Unable to retrieve share group." msgstr "Paylaşım grubu alınamıyor." msgid "Unable to retrieve share groups." msgstr "Paylaşım grupları alınamadı." msgid "Unable to retrieve share instance details." msgstr "Paylaşım sunucusu ayrıntıları alınamadı." msgid "Unable to retrieve share instances." msgstr "Paylaşım sunucuları alınamadı." msgid "Unable to retrieve share limit information." msgstr "Paylaşım sınır bilgisi alınamadı." msgid "Unable to retrieve share list." msgstr "Paylaşım listesi alınamadı." msgid "Unable to retrieve share network details." msgstr "Paylaşım ağı ayrıntıları alınamıyor." msgid "Unable to retrieve share network." msgstr "Paylaşım ağı alınamadı." msgid "Unable to retrieve share networks" msgstr "Paylaşım ağları alınamadı" msgid "Unable to retrieve share replicas." msgstr "Paylaşım kopyaları alınamadı." msgid "Unable to retrieve share rules." msgstr "Paylaşım kuralları alınamadı." msgid "Unable to retrieve share server details." msgstr "Paylaşım sunucusu ayrıntıları alınamıyor." msgid "Unable to retrieve share servers" msgstr "Paylaşım sunucuları alınamadı" msgid "Unable to retrieve share snapshot list." msgstr "Paylaşım anlık görüntü listesi alınamadı." msgid "Unable to retrieve share snapshot rules." msgstr "Paylaşım anlık görüntü kuralları alınamadı." msgid "Unable to retrieve share snapshot." msgstr "Paylaşım anlık görüntüsü alınamıyor." msgid "Unable to retrieve share snapshots list." msgstr "Paylaşım anlık görüntü listesi alınamıyor." msgid "Unable to retrieve share snapshots." msgstr "Paylaşım anlık görüntüleri alınamadı." msgid "Unable to retrieve share types." msgstr "Paylaşım türleri alınamadı." msgid "Unable to retrieve share." msgstr "Paylaşım alınamıyor." #, python-format msgid "Unable to retrieve share. %s" msgstr "Paylaşım alınamıyor. %s" msgid "Unable to retrieve share_gruop_type." msgstr "Paylaşım grup bütür alınamadı." msgid "Unable to retrieve share_type." msgstr "share_type alınamadı." msgid "Unable to retrieve snapshot details." msgstr "Anlık görüntü ayrıntıları alınamıyor." msgid "Unable to retrieve snapshot." msgstr "Anlık görüntü alınamıyor." msgid "Unable to retrieve volume details." msgstr "Birim ayrıntıları alınamıyor." msgid "Unable to revert share to the snapshot." msgstr "Paylaşım anlık görüntüye geri alınamadı." #, python-format msgid "Unable to set replica '%s' as active." msgstr "'%s' kopyası etkin olarak ayarlanamadı." msgid "Unable to unmanage share." msgstr "Paylaşım yönetim iptali başarısız." #, python-format msgid "Unable to update access for share group type \"%s\"." msgstr "\"%s\" paylaşım grubu türü için erişim güncellenemedi." #, python-format msgid "Unable to update access for share type \"%s\"." msgstr "Paylaşım türü \"%s\" için erişim güncellenemiyor." msgid "Unable to update default quotas." msgstr "Öntanımlı kotalar güncellenemedi." msgid "Unable to update group_specs for share group type." msgstr "Paylaşım grubu türü için grup özellikleri güncellenemedi." msgid "Unable to update security service." msgstr "Güvenlik servisi güncellenemedi." msgid "Unable to update share group snapshot." msgstr "Paylaşım grubu anlık görüntüsü güncellenemedi." msgid "Unable to update share group type." msgstr "Paylaşım grubu türü güncellenemedi." msgid "Unable to update share group." msgstr "Paylaşım grubu güncellenemiyor." msgid "Unable to update share metadata." msgstr "Paylaşım metaverisi güncellenemedi." #, python-format msgid "Unable to update share network \"%s\"." msgstr "Paylaşım ağı \"%s\" güncellenemedi." msgid "Unable to update share network." msgstr "Paylaşım ağı güncellenemedi." msgid "Unable to update share snapshot." msgstr "Paylaşım anlık görüntüsü güncellenemedi." msgid "Unable to update share type." msgstr "Paylaşım türü güncellenemiyor." msgid "Unable to update share." msgstr "Paylaşım güncellenemedi." msgid "Unknown" msgstr "Bilinmiyor" msgid "Unmanage" msgstr "Yönetimi Bırak" msgctxt "Current status of share" msgid "Unmanage Error" msgstr "Yönetimi Bırakma Hatası" msgid "Unmanage Share" msgstr "Paylaşım Yönetimini Bırak" msgid "Update" msgstr "Güncelle" msgid "Update Share Group" msgstr "Paylaşım Grubunu Güncelle" msgid "Update Share Group Snapshot" msgstr "Paylaşım Grubu Anlık Görüntüsünü Güncelle" msgid "Update Share Group Type" msgstr "Paylaşım Grubu Türünü Güncelle" msgid "Update Share Network" msgstr "Paylaşım Ağını Güncelle" msgid "Update Share Snapshot" msgstr "Paylaşım Anlık Görüntüsünü Güncelle" msgid "Update Share Type" msgstr "Paylaşım Türünü Güncelle" msgid "Update Share group Type" msgstr "Paylaşım grubu Türünü Güncelle" msgid "Updated At" msgstr "Güncelleme Zamanı" #, python-format msgid "Updated access for share group type \"%s\"." msgstr "\"%s\" paylaşım grubu türü için erişimi güncelle." #, python-format msgid "Updated access for share type \"%s\"." msgstr "\"%s\" paylaşım türü için erişim güncellendi." #, python-format msgid "Updated share network \"%s\"." msgstr "\"%s\" paylaşım ağı güncellendi." #, python-format msgid "Updating share \"%s\"" msgstr "\"%s\" paylaşımı güncelleniyor" #, python-format msgid "Updating share group \"%s\"" msgstr "\"%s\" paylaşım grubu güncelleniyor" #, python-format msgid "Updating share group snapshot \"%s\"" msgstr "Paylaşım grubu anlık görüntüsü \"%s\" güncelleniyor" #, python-format msgid "Updating share metadata \"%s\"" msgstr "Paylaşım metaverisi \"%s\" güncelleniyor" #, python-format msgid "Updating share network \"%s\"" msgstr "Paylaşım ağı \"%s\" güncelleniyor" #, python-format msgid "Updating share snapshot \"%s\"" msgstr "Paylaşım anlık görüntüsü \"%s\" güncelleniyor" msgid "Use share group snapshot as a source" msgstr "Paylaşım grubu anlık görüntüsünü kaynak olarak kullan" msgid "Use snapshot as a source" msgstr "Anlık görüntüyü kaynak olarak kullan" msgid "User" msgstr "Kullanıcı" msgid "Visibility" msgstr "Görünürlük" msgid "Writable" msgstr "Yazılabilir" msgid "key=value pairs per line can be set" msgstr "satır başına anahtar=değer çiftleri ayarlanabilir" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/0000775000175000017500000000000000000000000016570 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/__init__.py0000664000175000017500000000000000000000000020667 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/api/0000775000175000017500000000000000000000000017341 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/api/__init__.py0000664000175000017500000000000000000000000021440 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/api/test_manila.py0000664000175000017500000012377500000000000022232 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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 ddt from openstack_dashboard.api import base as horizon_api from manila_ui.api import manila as api from manila_ui.tests import helpers as base @ddt.ddt class ManilaApiTests(base.APITestCase): def setUp(self): super(self.__class__, self).setUp() self.id = "fake_id" self.mock_object(horizon_api, "QuotaSet") # Share tests @ddt.data( {}, None, {"name": "fake_share"}, {"limit": "3"}, {"host": "fake_share_host"}, {"sort_key": "id", "sort_dir": "asc"}, ) def test_share_list(self, kwargs): result = api.share_list(self.request, search_opts=kwargs) self.assertEqual( self.manilaclient.shares.list.return_value, result) expected_kwargs = kwargs or {} self.manilaclient.shares.list.assert_called_once_with( search_opts=expected_kwargs) def test_share_get(self): api.share_get(self.request, self.id) self.manilaclient.shares.get.assert_called_once_with(self.id) @ddt.data((None, True), ("some_fake_sg_id", False)) @ddt.unpack def test_share_create(self, sg_id, is_public): kwargs = { "share_network": "fake_sn", "snapshot_id": "fake_snapshot_id", "metadata": {"k1": "v1", "k2": "v2"}, "share_type": "fake_st", "is_public": is_public, "availability_zone": "fake_az", "share_group_id": sg_id, } size = 5 name = "fake_name" desc = "fake_description" proto = "fake_share_protocol" api.share_create(self.request, size, name, desc, proto, **kwargs) self.manilaclient.shares.create.assert_called_once_with( proto, size, name=name, description=desc, **kwargs) @ddt.data(None, "some_fake_sg_id") def test_share_delete(self, sg_id): s_id = "fake_share_id" api.share_delete(self.request, s_id, sg_id) self.manilaclient.shares.delete.assert_called_once_with( s_id, share_group_id=sg_id) @ddt.data(("", "", True), ("share_name", "", True), ("share_name", "share_description", True), ("", "share_description", True), ("", "", False), ("share_name", "", False), ("share_name", "share_description", False), ("", "share_description", False)) @ddt.unpack def test_share_update(self, name, description, is_public): api.share_update(self.request, self.id, name, description, is_public) self.manilaclient.shares.update.assert_called_once_with( self.id, display_name=name, display_description=description, is_public=is_public) # Shares ACLs tests def test_share_rules_list(self): result = api.share_rules_list(self.request, self.id) self.assertEqual( self.manilaclient.share_access_rules. access_list.return_value, result) self.manilaclient.share_access_rules.\ access_list.assert_called_once_with(self.id) def test_share_rule_get(self): result = api.share_rule_get(self.request, self.id) self.assertEqual( self.manilaclient.share_access_rules.get. return_value, result) self.manilaclient.share_access_rules.get.\ assert_called_once_with(self.id) def test_share_rule_set_metadata(self): fake_metadata = { "aim": "testing", "project": "test", } api.share_rule_set_metadata( self.request, self.id, fake_metadata) self.manilaclient.share_access_rules.\ set_metadata.assert_called_once_with(self.id, fake_metadata) def test_share_rule_unset_metadata(self): fake_key = "test" api.share_rule_unset_metadata( self.request, self.id, fake_key) self.manilaclient.share_access_rules.\ unset_metadata.assert_called_once_with(self.id, fake_key) def test_list_share_export_locations(self): api.share_export_location_list(self.request, self.id) self.manilaclient.share_export_locations.list.assert_called_once_with( self.id) def test_list_share_instance_export_locations(self): api.share_instance_export_location_list(self.request, self.id) client = self.manilaclient client.share_instance_export_locations.list.assert_called_once_with( self.id) @ddt.data(("ip", "10.0.0.13", "rw", {'testkey': "testval"}), ("ip", "10.0.0.13", None, None), ("ip", "10.0.0.13", "ro", {'key1': "val1"}), ("user", "demo", "rw", {'key2': "val2"}), ("user", "demo", None, None), ("user", "demo", "ro", None), ("cephx", "alice", "rw", {'test': "some"}), ("cephx", "alice", None, None), ("cephx", "alice", "ro", None)) @ddt.unpack def test_share_allow(self, access_type, access_to, access_level, metadata): api.share_allow(self.request, self.id, access_type, access_to, access_level, metadata) self.manilaclient.shares.allow.assert_called_once_with( self.id, access_type, access_to, access_level, metadata) def test_share_deny(self): fake_rule_id = "fake_rule_id" api.share_deny(self.request, self.id, fake_rule_id) self.manilaclient.shares.deny.assert_called_once_with( self.id, fake_rule_id) # Share manage/unmanage tests def test_share_manage(self): api.share_manage( self.request, service_host="fake_service_host", protocol="fake_protocol", export_path="fake_export_path", driver_options={"fake_key": "fake_value"}, share_type="fake_share_type", name="fake_name", description="fake_description", is_public="fake_is_public", ) self.manilaclient.shares.manage.assert_called_once_with( service_host="fake_service_host", protocol="fake_protocol", export_path="fake_export_path", driver_options={"fake_key": "fake_value"}, share_type="fake_share_type", name="fake_name", description="fake_description", is_public="fake_is_public", ) def test_share_unmanage(self): api.share_unmanage(self.request, self.id) self.manilaclient.shares.unmanage.assert_called_once_with(self.id) # Share migration tests def test_migration_start(self): api.migration_start(self.request, 'fake_share', 'fake_host', False, True, True, True, True, 'fake_net_id', 'fake_type_id') self.manilaclient.shares.migration_start.assert_called_once_with( 'fake_share', host='fake_host', force_host_assisted_migration=False, nondisruptive=True, writable=True, preserve_metadata=True, preserve_snapshots=True, new_share_network_id='fake_net_id', new_share_type_id='fake_type_id' ) def test_migration_complete(self): api.migration_complete(self.request, 'fake_share') self.manilaclient.shares.migration_complete.assert_called_once_with( 'fake_share') def test_migration_cancel(self): api.migration_cancel(self.request, 'fake_share') self.manilaclient.shares.migration_cancel.assert_called_once_with( 'fake_share') @ddt.data( ('name_updated_1', 'description_updated', True), ('name_updated_2', 'description_updated', False), ('name_updated_3', None, True), ) @ddt.unpack def test_share_type_update( self, name, description, is_public): api.share_type_update(self.request, self.id, name, description, is_public) self.manilaclient.share_types.get.return_value.update.\ assert_called_once_with(name=name, description=description, is_public=is_public) def test_migration_get_progress(self): api.migration_get_progress(self.request, 'fake_share') (self.manilaclient.shares.migration_get_progress. assert_called_once_with('fake_share')) # Share resize tests @ddt.data(("123", "78"), ("2", "5"), ("75", "21"), ("0", "2"), ("18", "62"), ("-1", "3")) @ddt.unpack def test_share_resize(self, new_size, orig_size): api.share_resize(self.request, self.id, new_size, orig_size) if orig_size > new_size: self.manilaclient.shares.shrink.assert_called_once_with( self.id, new_size) else: self.manilaclient.shares.extend.assert_called_once_with( self.id, new_size) # Share snapshots tests def test_share_revert(self): share = 'fake_share' snapshot = 'fake_snapshot' api.share_revert(self.request, share, snapshot) self.manilaclient.shares.revert_to_snapshot.assert_called_once_with( share, snapshot) def test_share_snapshot_get(self): snapshot = 'fake_snapshot' api.share_snapshot_get(self.request, snapshot) self.manilaclient.share_snapshots.get.assert_called_once_with(snapshot) @ddt.data(("", ""), ("share_name", ""), ("share_name", "share_description"), ("", "share_description"),) @ddt.unpack def test_share_snapshot_update(self, name, description): snapshot = 'fake_snapshot' api.share_snapshot_update(self.request, snapshot, name, description) self.manilaclient.share_snapshots.update.assert_called_once_with( snapshot, display_name=name, display_description=description) @ddt.data( {}, {"detailed": True}, {"detailed": False}, {"search_opts": {"foo": "bar"}}, {"sort_key": "id", "sort_dir": "asc"}, ) def test_share_snapshot_list(self, kwargs): result = api.share_snapshot_list(self.request, **kwargs) self.assertEqual( self.manilaclient.share_snapshots.list.return_value, result) self.manilaclient.share_snapshots.list.assert_called_once_with( detailed=kwargs.get("detailed", True), search_opts=kwargs.get("search_opts"), sort_key=kwargs.get("sort_key"), sort_dir=kwargs.get("sort_dir"), ) @ddt.data(True, False) def test_snapshot_create(self, force): name = 'fake_snapshot_name' description = "fake_snapshot_description" api.share_snapshot_create( self.request, self.id, name, description, force) self.manilaclient.share_snapshots.create.assert_called_once_with( self.id, name=name, description=description, force=force) def test_snapshot_delete(self): snapshot_id = 'fake_snapshot_id' api.share_snapshot_delete(self.request, snapshot_id) self.manilaclient.share_snapshots.delete.assert_called_once_with( snapshot_id) def test_allow_snapshot(self): access_type = "fake_type" access_to = "fake_value" api.share_snapshot_allow(self.request, self.id, access_type, access_to) client = self.manilaclient client.share_snapshots.allow.assert_called_once_with( self.id, access_type, access_to) def test_deny_snapshot(self): api.share_snapshot_deny(self.request, self.id, self.id) client = self.manilaclient client.share_snapshots.deny.assert_called_once_with(self.id, self.id) def test_list_snapshot_rules(self): api.share_snapshot_rules_list(self.request, self.id) client = self.manilaclient client.share_snapshots.access_list.assert_called_once_with(self.id) def test_list_snapshot_export_locations(self): api.share_snap_export_location_list(self.request, self.id) client = self.manilaclient client.share_snapshot_export_locations.list.assert_called_once_with( snapshot=self.id) def test_list_snapshot_instance_export_locations(self): api.share_snap_instance_export_location_list(self.request, self.id) client = self.manilaclient client.share_snapshot_export_locations.list.assert_called_once_with( snapshot_instance=self.id) # Share network tests @ddt.data( {}, {"detailed": True}, {"detailed": False}, {"detailed": False, "search_opts": {"foo": "bar"}}, ) def test_share_network_list(self, kwargs): api.share_network_list(self.request, **kwargs) self.manilaclient.share_networks.list.assert_called_once_with( detailed=kwargs.get("detailed", False), search_opts=kwargs.get("search_opts", None)) @ddt.data( {}, {"name": "foo_name"}, {"description": "foo_desc"}, {"neutron_net_id": "foo_neutron_net_id"}, {"neutron_subnet_id": "foo_neutron_subnet_id"}, {"name": "foo_name", "description": "foo_desc", "neutron_net_id": "foo_neutron_net_id", "neutron_subnet_id": "foo_neutron_subnet_id"}, ) def test_share_network_create(self, kwargs): expected_kwargs = { "name": None, "description": None, "neutron_net_id": None, "neutron_subnet_id": None, "availability_zone": None } expected_kwargs.update(**kwargs) api.share_network_create(self.request, **kwargs) mock_sn_create = self.manilaclient.share_networks.create mock_sn_create.assert_called_once_with(**expected_kwargs) def test_share_network_get(self): share_net_id = 'fake_share_net_id' api.share_network_get(self.request, share_net_id) self.manilaclient.share_networks.get.assert_called_once_with( share_net_id) @ddt.data(("", ""), ("share_net_name", ""), ("share_net_name", "share_net_description"), ("", "share_net_description")) @ddt.unpack def test_share_network_update(self, name, description): share_net_id = "fake_share_network" api.share_network_update(self.request, share_net_id, name, description) self.manilaclient.share_networks.update.assert_called_once_with( share_net_id, name=name, description=description) def test_share_network_delete(self): share_network_id = "fake_share_network" api.share_network_delete(self.request, share_network_id) self.manilaclient.share_networks.delete.assert_called_once_with( share_network_id) # Share server tests @ddt.data( {}, {"name": "fake_share_server"}, {"limit": "10"}, {"host": "fake_share_server_host"}, {"sort_key": "id", "sort_dir": "asc"}, ) def test_share_server_list(self, kwargs): result = api.share_server_list(self.request, search_opts=kwargs) self.assertEqual( self.manilaclient.share_servers.list.return_value, result) self.manilaclient.share_servers.list.assert_called_once_with( search_opts=kwargs) def test_share_server_get(self): share_serv_id = 'fake_share_server' api.share_server_get(self.request, share_serv_id) self.manilaclient.share_servers.get.assert_called_once_with( share_serv_id) def test_share_server_delete(self): share_serv_id = "fake_share_server" api.share_server_delete(self.request, share_serv_id) self.manilaclient.share_servers.delete.assert_called_once_with( share_serv_id) # Security service tests @ddt.data( {}, {"search_opts": {"foo": "bar"}}, ) def test_security_service_list(self, kwargs): api.security_service_list(self.request, **kwargs) self.manilaclient.security_services.list.assert_called_once_with( detailed=True, search_opts=kwargs.get("search_opts", None)) def test_security_service_get(self): sec_service_id = 'fake_sec_service_id' api.security_service_get(self.request, sec_service_id) self.manilaclient.security_services.get.assert_called_once_with( sec_service_id) @ddt.data( ("ldap", {}), ("kerberos", {}), ("ldap", {"dns_ip": "8.8.8.8", "ou": "fakeOU", "name": "my_fake_ldap_security_service", "description": "LDAP security service"}), ("kerberos", {"server": "10.254.0.3", "user": "demo", "password": "s3cr37", "name": "my_fake_kerberos_security_service", "description": "Kerberos security service"}) ) @ddt.unpack def test_security_service_create(self, ss_type, kwargs): expected_kwargs = { "dns_ip": None, "ou": None, "server": None, "domain": None, "password": None, "user": None, "name": None, "description": None } expected_kwargs.update(**kwargs) api.security_service_create(self.request, ss_type, **kwargs) mock_sec_service_create = self.manilaclient.security_services.create mock_sec_service_create.assert_called_once_with( ss_type, **expected_kwargs) @ddt.data( {"dns_ip": "8.8.4.4", "ou": "testOU", "server": "10.254.0.3", "domain": "None", "password": "wr67p6", "user": "demo", "name": "my_fake_ldap_security_service_2", "description": "LDAP security service 2"}, {"dns_ip": "None", "ou": "None", "server": "10.254.0.10", "domain": "None", "password": "None", "user": "demo", "name": "my_fake_kerberos_security_service_2", "description": "Kerberos security service 2"} ) def test_security_service_update(self, kwargs): sec_service_id = "fake_sec_service_id" api.security_service_update(self.request, sec_service_id, **kwargs) mock_sec_service_update = self.manilaclient.security_services.update mock_sec_service_update.assert_called_once_with( sec_service_id, **kwargs) def test_security_service_delete(self): sec_service_id = "fake_sec_service_id" api.security_service_delete(self.request, sec_service_id) self.manilaclient.security_services.delete.assert_called_once_with( sec_service_id) # Share network security service tests def test_share_network_security_service_add(self): share_network_id = "fake_share_net_id" sec_service_id = "fake_sec_service_id" api.share_network_security_service_add( self.request, share_network_id, sec_service_id) mock_sn_sec_service_add = ( self.manilaclient.share_networks.add_security_service) mock_sn_sec_service_add.assert_called_once_with( share_network_id, sec_service_id) def test_share_network_security_service_remove(self): share_network_id = "fake_share_net_id" sec_service_id = "fake_sec_service_id" api.share_network_security_service_remove( self.request, share_network_id, sec_service_id) mock_sn_sec_service_rm = ( self.manilaclient.share_networks.remove_security_service) mock_sn_sec_service_rm.assert_called_once_with( share_network_id, sec_service_id) def test_share_network_security_service_list(self): share_network_id = "fake_share_net_id" api.share_network_security_service_list( self.request, share_network_id) search_opts = {"share_network_id": share_network_id} self.manilaclient.security_services.list.assert_called_once_with( search_opts=search_opts) # Share metadata tests def test_share_set_metadata(self): fake_metadata = { "aim": "testing", "project": "my_abc", "deadline": "01/01/2020" } api.share_set_metadata( self.request, self.id, fake_metadata) self.manilaclient.shares.set_metadata.assert_called_once_with( self.id, fake_metadata) def test_share_delete_metadata(self): fake_keys = ["aim", "project", "deadline"] api.share_delete_metadata( self.request, self.id, fake_keys) self.manilaclient.shares.delete_metadata.assert_called_once_with( self.id, fake_keys) # Default quota tests def test_default_quota_get(self): project_id = 'fake_project_id' api.tenant_quota_get(self.request, project_id) self.manilaclient.quotas.get.assert_called_once_with(project_id) @ddt.data( ({'share_gigabytes': 333}, {'gigabytes': 333}), ({'share_snapshot_gigabytes': 444}, {'snapshot_gigabytes': 444}), ({'share_snapshots': 14}, {'snapshots': 14}), ({'snapshots': 14}, {'snapshots': 14}), ({'gigabytes': 14}, {'gigabytes': 14}), ({'snapshot_gigabytes': 314}, {'snapshot_gigabytes': 314}), ({'shares': 24}, {'shares': 24}), ({'share_networks': 14}, {'share_networks': 14}), ) @ddt.unpack def test_tenant_quota_update(self, provided_kwargs, expected_kwargs): tenant_id = 'fake_tenant_id' api.tenant_quota_update(self.request, tenant_id, **provided_kwargs) self.manilaclient.quotas.update.assert_called_once_with( tenant_id, **expected_kwargs) self.manilaclient.quota_classes.update.assert_not_called() @ddt.data( ({'share_gigabytes': 333}, {'gigabytes': 333}), ({'share_snapshot_gigabytes': 444}, {'snapshot_gigabytes': 444}), ({'share_snapshots': 14}, {'snapshots': 14}), ({'snapshots': 14}, {'snapshots': 14}), ({'gigabytes': 14}, {'gigabytes': 14}), ({'snapshot_gigabytes': 314}, {'snapshot_gigabytes': 314}), ({'shares': 24}, {'shares': 24}), ({'share_networks': 14}, {'share_networks': 14}), ) @ddt.unpack def test_default_quota_update(self, provided_kwargs, expected_kwargs): api.default_quota_update(self.request, **provided_kwargs) self.manilaclient.quota_classes.update.assert_called_once_with( api.DEFAULT_QUOTA_NAME, **expected_kwargs) def test_tenant_quota_get(self): tenant_id = 'fake_tenant_id' result = api.tenant_quota_get(self.request, tenant_id) self.assertIsNotNone(result) self.manilaclient.quotas.get.assert_called_once_with(tenant_id) @ddt.data({ 'shares': 24, 'gigabytes': 333, 'snapshots': 14, 'snapshot_gigabytes': 444, 'share_networks': 14, "share_groups": 30, "share_group_snapshots": 5, }) @ddt.unpack def test_ui_data_map(self, **kwargs): expected_result = { 'shares': 24, 'share_gigabytes': 333, 'share_snapshots': 14, 'share_snapshot_gigabytes': 444, 'share_networks': 14, "share_groups": 30, "share_group_snapshots": 5, } converted_result_for_ui = {} for field in api.MANILA_QUOTA_FIELDS: converted_result_for_ui[field] = ( kwargs[api.MANILA_QUOTA_FIELDS_DATA_MAP[field]]) self.assertEqual(expected_result, converted_result_for_ui) # Share type tests def test_share_type_list(self): api.share_type_list(self.request) self.manilaclient.share_types.list.assert_called_once_with() def test_share_type_get(self): share_type_id = "fake_share_type_id" api.share_type_get(self.request, share_type_id) self.manilaclient.share_types.get.assert_called_once_with( share_type_id) @ddt.data(True, False) def test_share_type_create_with_default_values(self, dhss): name = 'fake_share_type_name' api.share_type_create(self.request, name, dhss) self.manilaclient.share_types.create.assert_called_once_with( name=name, spec_driver_handles_share_servers=dhss, description=None, is_public=True) @ddt.data( (True, "fake_description", True), (False, "fake_description", True), (True, "fake_description", False), (False, "fake_description", False), ) @ddt.unpack def test_share_type_create_with_custom_values( self, dhss, description, is_public): name = 'fake_share_type_name' api.share_type_create( self.request, name, dhss, description, is_public) self.manilaclient.share_types.create.assert_called_once_with( name=name, description=description, spec_driver_handles_share_servers=dhss, is_public=is_public) def test_share_type_delete(self): share_type_id = "fake_share_type_id" api.share_type_delete(self.request, share_type_id) self.manilaclient.share_types.delete.assert_called_once_with( share_type_id) def test_share_type_get_extra_specs(self): share_type_id = "fake_share_type_id" api.share_type_get_extra_specs(self.request, share_type_id) share_types_get = self.manilaclient.share_types.get share_types_get.assert_called_once_with(share_type_id) share_types_get.return_value.get_keys.assert_called_once() def test_share_type_set_extra_specs(self): data = {"foo": "bar"} api.share_type_set_extra_specs(self.request, self.id, data) share_types_get = self.manilaclient.share_types.get share_types_get.assert_called_once_with(self.id) share_types_get.return_value.set_keys.assert_called_once_with(data) def test_share_type_unset_extra_specs(self): keys = ["foo", "bar"] api.share_type_unset_extra_specs(self.request, self.id, keys) share_types_get = self.manilaclient.share_types.get share_types_get.assert_called_once_with(self.id) share_types_get.return_value.unset_keys.assert_called_once_with(keys) def test_share_type_access_list(self): share_type_id = "fake_share_type_id" api.share_type_access_list(self.request, share_type_id) self.manilaclient.share_type_access.list.assert_called_once_with( share_type_id) def test_share_type_access_add(self): share_type_id = "fake_share_type_id" project_id = "fake_project_id" api.share_type_access_add(self.request, share_type_id, project_id) mock_share_type_access_add = ( self.manilaclient.share_type_access.add_project_access) mock_share_type_access_add.assert_called_once_with( share_type_id, project_id) def test_share_type_access_remove(self): share_type_id = "fake_share_type_id" project_id = "fake_project_id" api.share_type_access_remove(self.request, share_type_id, project_id) mock_share_type_access_rm = ( self.manilaclient.share_type_access.remove_project_access) mock_share_type_access_rm.assert_called_once_with( share_type_id, project_id) # Share replica tests def test_share_replica_list(self): api.share_replica_list(self.request) self.manilaclient.share_replicas.list.assert_called_once_with(None) def test_share_replica_list_with_filter_by_share(self): api.share_replica_list(self.request, share="FOO") self.manilaclient.share_replicas.list.assert_called_once_with("FOO") def test_share_replica_create(self): share = "FOO_share" availability_zone = "BAR_availability_zone" api.share_replica_create( self.request, share, availability_zone) self.manilaclient.share_replicas.create.assert_called_once_with( share, availability_zone=availability_zone ) def test_share_replica_get(self): api.share_replica_get(self.request, "fake") self.manilaclient.share_replicas.get.assert_called_once_with("fake") def test_share_replica_delete(self): api.share_replica_delete(self.request, "fake") self.manilaclient.share_replicas.delete.assert_called_once_with("fake") def test_share_replica_promote(self): api.share_replica_promote(self.request, "fake") self.manilaclient.share_replicas.promote.assert_called_once_with( "fake") def test_share_replica_resync(self): api.share_replica_resync(self.request, "fake") self.manilaclient.share_replicas.resync.assert_called_once_with("fake") def test_share_replica_reset_status(self): replica = "fake_replica" status = "fake_status" api.share_replica_reset_status(self.request, replica, status) self.manilaclient.share_replicas.reset_state.assert_called_once_with( replica, status) def test_share_replica_reset_state(self): replica = "fake_replica" state = "fake_state" api.share_replica_reset_state(self.request, replica, state) mock_reset_state = self.manilaclient.share_replicas.reset_replica_state mock_reset_state.assert_called_once_with(replica, state) # Share instance tests def test_share_instance_list(self): api.share_instance_list(self.request) self.manilaclient.share_instances.list.assert_called_once_with() def test_share_instance_get(self): api.share_instance_get(self.request, self.id) self.manilaclient.share_instances.get.assert_called_once_with(self.id) # Availability zone and pool tests def test_availability_zone_list(self): api.availability_zone_list(self.request) self.manilaclient.availability_zones.list.assert_called_once_with() @ddt.data({}, {"detailed": True}, {"detailed": False}) def test_pool_list(self, kwargs): api.pool_list(self.request, **kwargs) self.manilaclient.pools.list.assert_called_once_with( detailed=kwargs.get("detailed", False)) # Share groups tests def test_share_group_create(self): name = "fake_sg_name" kwargs = { "description": "fake_desc", "share_group_type": "fake_sg_type", "share_types": ["fake", "list", "of", "fake", "share", "types"], "share_network": "fake_sn", "source_share_group_snapshot": "fake_source_share_group_snapshot", "availability_zone": "fake_az", } result = api.share_group_create(self.request, name, **kwargs) self.assertEqual( self.manilaclient.share_groups.create.return_value, result) self.manilaclient.share_groups.create.assert_called_once_with( name=name, **kwargs) def test_share_group_get(self): sg = "fake_share_group" result = api.share_group_get(self.request, sg) self.assertEqual( self.manilaclient.share_groups.get.return_value, result) self.manilaclient.share_groups.get.assert_called_once_with(sg) def test_share_group_update(self): sg = "fake_share_group" name = "fake_name" desc = "fake_desc" result = api.share_group_update(self.request, sg, name, desc) self.assertEqual( self.manilaclient.share_groups.update.return_value, result) self.manilaclient.share_groups.update.assert_called_once_with( sg, name=name, description=desc) @ddt.data({}, {"force": True}, {"force": False}) def test_share_group_delete(self, kwargs): sg = 'fake_share_group' api.share_group_delete(self.request, sg, **kwargs) self.manilaclient.share_groups.delete.assert_called_once_with( sg, force=kwargs.get("force", False)) def test_share_group_reset_state(self): sg = 'fake_share_group' state = 'fake_state' result = api.share_group_reset_state(self.request, sg, state) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_groups.reset_state.return_value, result) self.manilaclient.share_groups.reset_state.assert_called_once_with( sg, state) @ddt.data( {}, {"detailed": True}, {"detailed": False}, {"search_opts": {"foo": "bar"}}, {"sort_key": "id", "sort_dir": "asc"}, ) def test_share_group_list(self, kwargs): result = api.share_group_list(self.request, **kwargs) self.assertEqual( self.manilaclient.share_groups.list.return_value, result) self.manilaclient.share_groups.list.assert_called_once_with( detailed=kwargs.get("detailed", True), search_opts=kwargs.get("search_opts"), sort_key=kwargs.get("sort_key"), sort_dir=kwargs.get("sort_dir"), ) # Share Group Snapshots tests def test_share_group_snapshot_create(self): sg = 'fake_share_group' name = 'fake_name' desc = 'fake_description' result = api.share_group_snapshot_create(self.request, sg, name, desc) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_snapshots.create.return_value, result) self.manilaclient.share_group_snapshots.create.assert_called_once_with( share_group=sg, name=name, description=desc) def test_share_group_snapshot_get(self): sgs = 'fake_share_group_snapshot' result = api.share_group_snapshot_get(self.request, sgs) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_snapshots.get.return_value, result) self.manilaclient.share_group_snapshots.get.assert_called_once_with( sgs) def test_share_group_snapshot_update(self): sgs = 'fake_share_group_snapshot' name = 'fake_name' desc = 'fake_description' result = api.share_group_snapshot_update(self.request, sgs, name, desc) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_snapshots.update.return_value, result) self.manilaclient.share_group_snapshots.update.assert_called_once_with( sgs, name=name, description=desc) @ddt.data(True, False) def test_share_group_snapshot_delete(self, force): sgs = 'fake_share_group_snapshot' result = api.share_group_snapshot_delete(self.request, sgs, force) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_snapshots.delete.return_value, result) self.manilaclient.share_group_snapshots.delete.assert_called_once_with( sgs, force=force) def test_share_group_snapshot_reset_state(self): sgs = 'fake_share_group_snapshot' state = 'fake_state' result = api.share_group_snapshot_reset_state(self.request, sgs, state) rs_method = self.manilaclient.share_group_snapshots.reset_state self.assertIsNotNone(result) self.assertEqual(rs_method.return_value, result) rs_method.assert_called_once_with(sgs, state) @ddt.data( {}, {'detailed': False}, {'detailed': True, 'search_opts': 'foo', 'sort_key': 'k', 'sort_dir': 'v'}, ) def test_share_group_snapshot_list(self, kwargs): result = api.share_group_snapshot_list(self.request, **kwargs) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_snapshots.list.return_value, result) self.manilaclient.share_group_snapshots.list.assert_called_once_with( detailed=kwargs.get('detailed', True), search_opts=kwargs.get('search_opts'), sort_key=kwargs.get('sort_key'), sort_dir=kwargs.get('sort_dir')) # Share Group Types tests @ddt.data( {'is_public': True}, {'is_public': False, 'group_specs': {'foo': 'bar'}}, {'group_specs': {}}, ) def test_share_group_type_create(self, kwargs): name = 'fake_sgt_name' sts = ['fake', 'list', 'of', 'share', 'types'] result = api.share_group_type_create(self.request, name, sts, **kwargs) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_types.create.return_value, result) self.manilaclient.share_group_types.create.assert_called_once_with( name=name, share_types=sts, is_public=kwargs.get('is_public', False), group_specs=kwargs.get('group_specs')) def test_share_group_type_get(self): sgt = "fake_sgt" result = api.share_group_type_get(self.request, sgt) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_types.get.return_value, result) self.manilaclient.share_group_types.get.assert_called_once_with(sgt) @ddt.data(True, False) def test_share_group_type_list(self, show_all): result = api.share_group_type_list(self.request, show_all) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_types.list.return_value, result) self.manilaclient.share_group_types.list.assert_called_once_with( show_all=show_all) def test_share_group_type_delete(self): sgt = 'fake_share_group_type' result = api.share_group_type_delete(self.request, sgt) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_types.delete.return_value, result) self.manilaclient.share_group_types.delete.assert_called_once_with(sgt) def test_share_group_type_access_list(self): sgt = 'fake_share_group_type' result = api.share_group_type_access_list(self.request, sgt) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.share_group_type_access.list.return_value, result) self.manilaclient.share_group_type_access.list.assert_called_once_with( sgt) def test_share_group_type_access_add(self): sgt = 'fake_share_group_type' project = 'fake_project' result = api.share_group_type_access_add(self.request, sgt, project) sgt_access = self.manilaclient.share_group_type_access self.assertIsNotNone(result) self.assertEqual( sgt_access.add_project_access.return_value, result) sgt_access.add_project_access.assert_called_once_with(sgt, project) def test_share_group_type_access_remove(self): sgt = 'fake_share_group_type' project = 'fake_project' result = api.share_group_type_access_remove(self.request, sgt, project) sgt_access = self.manilaclient.share_group_type_access self.assertIsNotNone(result) self.assertEqual( sgt_access.remove_project_access.return_value, result) sgt_access.remove_project_access.assert_called_once_with(sgt, project) def test_share_group_type_set_specs(self): sgt = 'fake_share_group_type' group_specs = 'fake_specs' result = api.share_group_type_set_specs(self.request, sgt, group_specs) get_method = self.manilaclient.share_group_types.get self.assertIsNotNone(result) self.assertEqual(get_method.return_value.set_keys.return_value, result) get_method.assert_called_once_with(sgt) get_method.return_value.set_keys.assert_called_once_with(group_specs) def test_share_group_type_unset_specs(self): sgt = 'fake_share_group_type' keys = ['fake', 'list', 'of', 'keys', 'for', 'deletion'] result = api.share_group_type_unset_specs(self.request, sgt, keys) get_method = self.manilaclient.share_group_types.get self.assertIsNotNone(result) self.assertEqual( get_method.return_value.unset_keys.return_value, result) get_method.assert_called_once_with(sgt) get_method.return_value.unset_keys.assert_called_once_with(keys) def test_share_group_type_get_specs(self): sgt = 'fake_share_group_type' result = api.share_group_type_get_specs(self.request, sgt) get_method = self.manilaclient.share_group_types.get self.assertIsNotNone(result) self.assertEqual( get_method.return_value.get_keys.return_value, result) get_method.assert_called_once_with(sgt) get_method.return_value.get_keys.assert_called_once_with() @ddt.data(None, "some_fake_message_id") def test_share_messages_get(self, message_id): result = api.messages_get(self.request, message_id) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.messages.get.return_value, result) self.manilaclient.messages.get.assert_called_once_with(message_id) @ddt.data( {}, {'search_opts': 'foo', 'sort_key': 'k', 'sort_dir': 'v'}, ) def test_messages_list(self, kwargs): result = api.messages_list(self.request, **kwargs) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.messages.list.return_value, result) self.manilaclient.messages.list.assert_called_once_with( search_opts=kwargs.get('search_opts'), sort_key=kwargs.get('sort_key'), sort_dir=kwargs.get('sort_dir')) @ddt.data(None, "some_fake_message_id") def test_messages_delete(self, message_id): result = api.messages_delete(self.request, message_id) self.assertIsNotNone(result) self.assertEqual( self.manilaclient.messages.delete.return_value, result) self.manilaclient.messages.delete.assert_called_once_with(message_id) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/dashboards/0000775000175000017500000000000000000000000020702 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/__init__.py0000664000175000017500000000000000000000000023001 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/0000775000175000017500000000000000000000000021772 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/__init__.py0000664000175000017500000000000000000000000024071 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/security_services/0000775000175000017500000000000000000000000025544 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/security_services/__init__.py0000664000175000017500000000000000000000000027643 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/security_services/tests.py0000664000175000017500000000765600000000000027276 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from horizon import exceptions as horizon_exceptions from openstack_dashboard.api import keystone as api_keystone from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from manila_ui.tests.test_data import keystone_data INDEX_URL = reverse('horizon:admin:security_services:index') class SecurityServicesTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(keystone_data.projects, None))) # Reset taken list of projects to avoid test interference utils.PROJECTS = {} def test_detail_view(self): sec_service = test_data.sec_service self.mock_object( api_manila, "security_service_get", mock.Mock(return_value=sec_service)) url = reverse( 'horizon:admin:security_services:security_service_detail', args=[sec_service.id]) res = self.client.get(url) self.assertContains(res, "

Security Service Details: %s

" % sec_service.name, 1, 200) self.assertContains(res, "
%s
" % sec_service.name, 1, 200) self.assertContains(res, "
%s
" % sec_service.id, 1, 200) self.assertContains(res, "
%s
" % sec_service.user, 1, 200) self.assertContains(res, "
%s
" % sec_service.server, 1, 200) self.assertContains(res, "
%s
" % sec_service.dns_ip, 1, 200) self.assertContains(res, "
%s
" % sec_service.ou, 1, 200) self.assertContains(res, "
%s
" % sec_service.domain, 1, 200) self.assertNoMessages() api_manila.security_service_get.assert_called_once_with( mock.ANY, sec_service.id) def test_detail_view_with_exception(self): url = reverse( 'horizon:admin:security_services:security_service_detail', args=[test_data.sec_service.id]) self.mock_object( api_manila, "security_service_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.security_service_get.assert_called_once_with( mock.ANY, test_data.sec_service.id) def test_delete_security_service(self): security_service = test_data.sec_service formData = { 'action': 'security_services__delete__%s' % security_service.id, } self.mock_object(api_manila, "security_service_delete") self.mock_object( api_manila, "security_service_list", mock.Mock(return_value=[test_data.sec_service])) res = self.client.post(INDEX_URL, formData) api_keystone.tenant_list.assert_called_once_with(mock.ANY) api_manila.security_service_delete.assert_called_once_with( mock.ANY, test_data.sec_service.id) api_manila.security_service_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_group_snapshots/0000775000175000017500000000000000000000000026412 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_group_snapshots/__init__.py0000664000175000017500000000000000000000000030511 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_group_snapshots/tests.py0000664000175000017500000001762000000000000030134 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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 ddt from django.urls import reverse from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:admin:share_group_snapshots:index') @ddt.ddt class ShareGroupSnapshotTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.sg = test_data.share_group self.sg_nl = test_data.share_group_nameless self.sg_dhss_true = test_data.share_group_dhss_true self.sgs = test_data.share_group_snapshot self.sgs_nl = test_data.share_group_snapshot_nameless def test_share_group_snapshots_list_get(self): share_groups = [self.sg, self.sg_nl, self.sg_dhss_true] sgss = [self.sgs, self.sgs_nl] self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(return_value=sgss)) self.mock_object( api_manila, 'share_group_list', mock.Mock(return_value=share_groups)) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) self.assertMessageCount(error=0) self.assertNoMessages() api_manila.share_group_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) api_manila.share_group_list.assert_called_once_with(mock.ANY) self.assertTemplateUsed(res, 'admin/share_group_snapshots/index.html') self.assertContains(res, "

Share Group Snapshots

") self.assertContains( res, 'Delete Share Group Snapshot', len(sgss)) self.assertContains(res, 'Delete Share Group Snapshots', 1) for sgs in sgss: self.assertContains( res, 'href="/admin/share_group_snapshots/%s/reset_status"> ' 'Reset status' % sgs.id, 1) self.assertContains( res, 'value="share_group_snapshots__delete__%s' % sgs.id, 1) self.assertContains( res, '%(name)s' % { 'id': self.sgs.id, 'name': self.sgs.name}, 1) self.assertContains( res, '-' % self.sgs_nl.id, 1) def test_share_group_snapshots_list_error_get(self): self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) self.assertTemplateUsed(res, 'admin/share_group_snapshots/index.html') self.assertContains(res, "

Share Group Snapshots

") self.assertContains(res, 'Delete Share Group Snapshot', 0) self.assertContains(res, 'Delete Share Group Snapshots', 0) self.assertNoMessages() @ddt.data( test_data.share_group_snapshot, test_data.share_group_snapshot_nameless, ) def test_share_group_snapshot_detailed_page_get(self, sgs): sg = test_data.share_group_nameless url = reverse( 'horizon:admin:share_group_snapshots:detail', args=[sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=sgs)) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=sg)) res = self.client.get(url) self.assertTemplateUsed(res, 'admin/share_group_snapshots/detail.html') self.assertStatusCode(res, 200) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, sgs.id) api_manila.share_group_get.assert_called_once_with( mock.ANY, sgs.share_group_id) def test_share_group_snapshot_detailed_page_error_get(self): url = reverse( 'horizon:admin:share_group_snapshots:detail', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed( res, 'admin/share_group_snapshots/detail.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=1) self.assertMessageCount(success=0) def test_share_group_snapshot_reset_status_get(self): url = reverse( 'horizon:admin:share_group_snapshots:reset_status', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=self.sgs)) res = self.client.get(url) self.assertTemplateUsed( res, 'admin/share_group_snapshots/reset_status.html') self.assertStatusCode(res, 200) self.assertMessageCount(error=0) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) def test_share_group_snapshot_reset_status_error_get(self): url = reverse( 'horizon:admin:share_group_snapshots:reset_status', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed( res, 'admin/share_group_snapshots/reset_status.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=1) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) def test_share_group_snapshot_reset_status_post(self): url = reverse( 'horizon:admin:share_group_snapshots:reset_status', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=self.sgs)) self.mock_object(api_manila, 'share_group_snapshot_reset_state') form_data = {'status': 'error'} res = self.client.post(url, form_data) self.assertTemplateNotUsed( res, 'admin/share_group_snapshots/reset_status.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=0) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) api_manila.share_group_snapshot_reset_state.assert_called_once_with( mock.ANY, self.sgs.id, form_data['status']) self.assertRedirectsNoFollow(res, INDEX_URL) def test_share_group_snapshot_delete_post(self): data = {'action': 'share_group_snapshots__delete__%s' % self.sgs.id} self.mock_object(api_manila, "share_group_snapshot_delete") self.mock_object( api_manila, "share_group_snapshot_list", mock.Mock(return_value=[self.sgs])) res = self.client.post(INDEX_URL, data) self.assertStatusCode(res, 302) self.assertMessageCount(success=1) api_manila.share_group_snapshot_delete.assert_called_once_with( mock.ANY, self.sgs.id) api_manila.share_group_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_group_types/0000775000175000017500000000000000000000000025534 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_group_types/__init__.py0000664000175000017500000000000000000000000027633 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_group_types/tests.py0000664000175000017500000001052000000000000027246 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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. from django.urls import reverse from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:admin:share_group_types:index') class ShareGroupTypeTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.share_group_type = test_data.share_group_type self.share_group_type_alt = test_data.share_group_type_alt self.share_group_type_p = test_data.share_group_type_private self.url = reverse('horizon:admin:share_group_types:update', args=[self.share_group_type.id]) self.mock_object(api_manila, "share_group_type_get", mock.Mock(return_value=self.share_group_type)) def test_create_share_group_type(self): url = reverse('horizon:admin:share_group_types:create') data = { 'method': 'CreateShareGroupTypeForm', 'is_public': True, 'name': 'my_share_group_type', 'share_types': ['foo'], 'group_specs': 'key=value', } self.mock_object( api_manila, "share_group_type_create", mock.Mock(return_value=type( 'ShareGroupType', (object, ), {'id': 'sgt_id', 'name': 'sgt_name'}))) self.mock_object(api_manila, "share_group_type_set_specs") self.mock_object( api_manila, "share_type_list", mock.Mock(return_value=[type( 'ShareType', (object, ), {'id': s_id, 'name': s_id + '_name'}) for s_id in ('foo', 'bar') ])) res = self.client.post(url, data) api_manila.share_group_type_create.assert_called_once_with( mock.ANY, data['name'], is_public=data['is_public'], share_types=['foo']) api_manila.share_type_list.assert_called_once_with(mock.ANY) api_manila.share_group_type_set_specs.assert_called_once_with( mock.ANY, 'sgt_id', {'key': 'value'}) self.assertRedirectsNoFollow(res, INDEX_URL) def test_update_share_group_type_get(self): res = self.client.get(self.url) api_manila.share_group_type_get.assert_called_once_with( mock.ANY, self.share_group_type.id) self.assertNoMessages() self.assertTemplateUsed(res, 'admin/share_group_types/update.html') def test_update_share_group_type_post(self): data = {'group_specs': 'foo=bar'} form_data = {'group_specs': {'foo': 'bar'}} self.mock_object(api_manila, "share_group_type_set_specs") res = self.client.post(self.url, data) api_manila.share_group_type_set_specs.assert_called_once_with( mock.ANY, self.share_group_type.id, form_data['group_specs']) self.assertRedirectsNoFollow(res, INDEX_URL) def test_delete_share_group_type(self): data = {'action': 'share_group_types__delete__%s' % self.share_group_type_alt.id} self.mock_object(api_manila, "share_group_type_delete") self.mock_object( api_manila, "share_group_type_list", mock.Mock(return_value=[self.share_group_type_alt])) self.mock_object( api_manila, "share_type_list", mock.Mock(return_value=[test_data.share_type_alt])) res = self.client.post(INDEX_URL, data) api_manila.share_group_type_delete.assert_called_once_with( mock.ANY, self.share_group_type_alt.id) api_manila.share_group_type_list.assert_called_once_with( mock.ANY) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8346515 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_groups/0000775000175000017500000000000000000000000024473 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_groups/__init__.py0000664000175000017500000000000000000000000026572 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_groups/tests.py0000664000175000017500000002003200000000000026204 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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 ddt from django.urls import reverse from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:admin:share_groups:index') @ddt.ddt class ShareGroupTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.sg = test_data.share_group self.sg_nl = test_data.share_group_nameless self.sg_dhss_true = test_data.share_group_dhss_true def test_share_groups_list_get(self): sgs = [self.sg, self.sg_nl, self.sg_dhss_true] self.mock_object( api_manila, 'share_group_list', mock.Mock(return_value=sgs)) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) api_manila.share_group_list.assert_called_once_with( mock.ANY, detailed=True) self.assertTemplateUsed(res, 'admin/share_groups/index.html') self.assertContains(res, "

Share Groups

") self.assertContains(res, 'Delete Share Group', len(sgs)) self.assertContains(res, 'Delete Share Groups', 1) for sg in sgs: self.assertContains( res, 'href="/admin/share_groups/%s/reset_status"> ' 'Reset status' % sg.id, 1) self.assertContains( res, 'value="share_groups__delete__%s' % sg.id, 1) self.assertContains( res, '%(name)s' % { 'id': sg.id, 'name': sg.name}, 1) self.assertContains( res, '-' % self.sg_nl.id, 1) self.assertNoMessages() def test_share_group_list_error_get(self): self.mock_object( api_manila, 'share_group_list', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) self.assertTemplateUsed(res, 'admin/share_groups/index.html') self.assertContains(res, "

Share Groups

") self.assertContains(res, 'Delete Share Group', 0) self.assertContains(res, 'Delete Share Groups', 0) self.assertNoMessages() @ddt.data( test_data.share_group_nameless, test_data.share_group_dhss_true, ) def test_share_group_detailed_page_get(self, sg): url = reverse('horizon:admin:share_groups:detail', args=[sg.id]) shares = [test_data.share, test_data.nameless_share] share_types = [test_data.share_type, test_data.share_type_dhss_true] capability_msg = ("Consistent snapshots are supported at storage " if sg.consistent_snapshot_support else None) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=sg)) self.mock_object( api_manila, 'share_list', mock.Mock(return_value=shares)) self.mock_object(api_manila, 'share_group_type_get', mock.Mock(return_value=test_data.share_group_type)) self.mock_object(api_manila, 'share_type_list', mock.Mock(return_value=share_types)) res = self.client.get(url) self.assertTemplateUsed(res, 'admin/share_groups/detail.html') self.assertStatusCode(res, 200) self.assertContains(res, '
Capabilities
') self.assertContains(res, capability_msg) if capability_msg else None self.assertContains(res, "Share Group Type Name:") self.assertContains(res, "Share Group Type ID:") self.assertContains(res, "Share Group Type Specs:") for share in shares: data = {'id': share.id, 'name': share.name or share.id} self.assertContains( res, '%(name)s' % data) def test_share_group_detailed_page_error_get(self): sg = test_data.share_group_dhss_true url = reverse('horizon:admin:share_groups:detail', args=[sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(side_effect=type( 'CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed(res, 'admin/share_groups/detail.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=1) self.assertMessageCount(success=0) def test_share_group_reset_status_get(self): sg = test_data.share_group_dhss_true url = reverse('horizon:admin:share_groups:reset_status', args=[sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=sg)) res = self.client.get(url) self.assertTemplateUsed(res, 'admin/share_groups/reset_status.html') self.assertStatusCode(res, 200) self.assertMessageCount(error=0) api_manila.share_group_get.assert_called_once_with(mock.ANY, sg.id) def test_share_group_reset_status_error_get(self): sg = test_data.share_group_dhss_true url = reverse('horizon:admin:share_groups:reset_status', args=[sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed(res, 'admin/share_groups/reset_status.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=1) api_manila.share_group_get.assert_called_once_with(mock.ANY, sg.id) def test_share_group_reset_status_post(self): sg = test_data.share_group_dhss_true url = reverse('horizon:admin:share_groups:reset_status', args=[sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=sg)) self.mock_object(api_manila, 'share_group_reset_state') form_data = {'status': 'error'} res = self.client.post(url, form_data) self.assertTemplateNotUsed(res, 'admin/share_groups/reset_status.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=0) api_manila.share_group_get.assert_called_once_with(mock.ANY, sg.id) api_manila.share_group_reset_state.assert_called_once_with( mock.ANY, sg.id, form_data['status']) self.assertRedirectsNoFollow(res, INDEX_URL) def test_share_group_delete_post(self): sg = test_data.share_group_dhss_true data = {'action': 'share_groups__delete__%s' % sg.id} self.mock_object(api_manila, "share_group_delete") self.mock_object( api_manila, "share_group_list", mock.Mock(return_value=[sg])) res = self.client.post(INDEX_URL, data) self.assertStatusCode(res, 302) self.assertMessageCount(success=1) api_manila.share_group_delete.assert_called_once_with(mock.ANY, sg.id) api_manila.share_group_list.assert_called_once_with( mock.ANY, detailed=True) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_instances/0000775000175000017500000000000000000000000025143 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_instances/__init__.py0000664000175000017500000000000000000000000027242 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_instances/tests.py0000664000175000017500000001177000000000000026665 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from horizon import exceptions as horizon_exceptions from openstack_dashboard.api import keystone as api_keystone from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:admin:share_instances:index') class ShareInstanceTests(test.BaseAdminViewTests): def test_list_share_instances(self): share_instances = [ test_data.share_instance, test_data.share_instance_no_ss, ] self.mock_object( api_manila, "share_instance_list", mock.Mock(return_value=share_instances)) self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=([], None))) res = self.client.get(INDEX_URL) self.assertContains(res, "

Share Instances

") self.assertContains( res, '%s' % ( share_instances[0].share_server_id, share_instances[0].share_server_id), 1, 200) self.assertContains( res, '%s' % ( share_instances[0].share_network_id, share_instances[0].share_network_id), 1, 200) for si in share_instances: self.assertContains( res, '%s' % ( si.id, si.id)) self.assertContains(res, si.host) self.assertContains(res, si.availability_zone) self.assertContains( res, '%s' % ( si.share_id, si.share_id), 1, 200) api_manila.share_instance_list.assert_called_once_with(mock.ANY) self.assertEqual(0, api_keystone.tenant_list.call_count) def test_detail_view_share_instance(self): share_instance = test_data.share_instance share_id = share_instance.share_id ss_id = share_instance.share_server_id url = reverse('horizon:admin:share_instances:share_instance_detail', args=[share_instance.id]) self.mock_object( api_manila, "share_instance_get", mock.Mock(return_value=share_instance)) self.mock_object( api_manila, "share_instance_export_location_list", mock.Mock(return_value=test_data.export_locations)) res = self.client.get(url) self.assertContains( res, "

Share Instance Details: %s

" % share_instance.id, 1, 200) self.assertContains(res, "
%s
" % share_instance.id, 1, 200) self.assertContains(res, "
Available
", 1, 200) self.assertContains(res, "
%s
" % share_instance.host, 1, 200) self.assertContains( res, "
%s
" % share_instance.availability_zone, 1, 200) self.assertContains( res, "
%s
" % ( share_id, share_id), 1, 200) self.assertContains( res, "
%s
" % ( share_instance.share_network_id, share_instance.share_network_id), 1, 200) self.assertContains( res, "
%s
" % ( ss_id, ss_id), 1, 200) self.assertNoMessages() api_manila.share_instance_get.assert_called_once_with( mock.ANY, share_instance.id) api_manila.share_instance_export_location_list.assert_called_once_with( mock.ANY, share_instance.id) def test_detail_view_share_instance_with_exception(self): share_instance = test_data.share_instance url = reverse('horizon:admin:share_instances:share_instance_detail', args=[share_instance.id]) self.mock_object( api_manila, "share_instance_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_instance_get.assert_called_once_with( mock.ANY, share_instance.id) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_networks/0000775000175000017500000000000000000000000025030 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_networks/__init__.py0000664000175000017500000000000000000000000027127 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_networks/tests.py0000664000175000017500000002123400000000000026546 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from horizon import exceptions as horizon_exceptions from neutronclient.client import exceptions from openstack_dashboard.api import keystone as api_keystone from openstack_dashboard.api import neutron as api_neutron from oslo_utils import timeutils from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from manila_ui.tests.test_data import keystone_data INDEX_URL = reverse('horizon:admin:share_networks:index') class ShareNetworksTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(keystone_data.projects, None))) # Reset taken list of projects to avoid test interference utils.PROJECTS = {} class FakeAZ(object): def __init__(self, name, id): self.name = name self.id = id self.created_at = timeutils.utcnow() def test_detail_view(self): share_net = test_data.active_share_network share_network_subnets = share_net.share_network_subnets sec_service = test_data.sec_service self.mock_object( api_manila, "share_server_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_get", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "share_network_security_service_list", mock.Mock(return_value=[sec_service])) network = self.networks.first() subnet = self.subnets.first() self.mock_object( api_neutron, "network_get", mock.Mock(return_value=network)) self.mock_object( api_neutron, "subnet_get", mock.Mock(return_value=subnet)) self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[self.FakeAZ('fake_az', 'fake_az')]) ) url = reverse('horizon:admin:share_networks:share_network_detail', args=[share_net.id]) res = self.client.get(url) self.assertContains(res, "

Share Network Details: %s

" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.id, 1, 200) for sub in share_network_subnets: self.assertContains(res, "%s" % ( sub['neutron_net_id'], network.name), 1, 200) self.assertContains(res, "%s" % (sec_service.id, sec_service.name), 1, 200) network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id'] ) for sub in share_network_subnets] subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id'] ) for sub in share_network_subnets] api_neutron.network_get.assert_has_calls(network_get_calls, any_order=True) api_neutron.subnet_get.assert_has_calls(subnet_get_calls, any_order=True) self.assertNoMessages() api_manila.share_network_security_service_list.assert_called_once_with( mock.ANY, share_net.id) api_manila.share_server_list.assert_called_once_with( mock.ANY, search_opts={'share_network_id': share_net.id}) api_manila.share_network_get.assert_called_once_with( mock.ANY, share_net.id) def test_detail_view_network_not_found(self): share_net = test_data.active_share_network sec_service = test_data.sec_service share_network_subnets = share_net.share_network_subnets url = reverse('horizon:admin:share_networks:share_network_detail', args=[share_net.id]) self.mock_object( api_manila, "share_server_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_get", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "share_network_security_service_list", mock.Mock(return_value=[sec_service])) self.mock_object( api_neutron, "network_get", mock.Mock( side_effect=exceptions.NeutronClientException('fake', 500))) self.mock_object( api_neutron, "subnet_get", mock.Mock( side_effect=exceptions.NeutronClientException('fake', 500))) self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[]) ) res = self.client.get(url) self.assertContains(res, "

Share Network Details: %s

" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.id, 1, 200) for sub in share_network_subnets: self.assertNotContains(res, "
%s
" % sub['neutron_net_id']) self.assertNotContains(res, "
%s
" % sub['neutron_subnet_id']) network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id'] ) for sub in share_network_subnets] subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id'] ) for sub in share_network_subnets] api_neutron.network_get.assert_has_calls(network_get_calls, any_order=True) api_neutron.subnet_get.assert_has_calls(subnet_get_calls, any_order=True) self.assertContains(res, "%s" % (sec_service.id, sec_service.name), 1, 200) self.assertNoMessages() api_manila.share_network_security_service_list.assert_called_once_with( mock.ANY, share_net.id) api_manila.share_server_list.assert_called_once_with( mock.ANY, search_opts={'share_network_id': share_net.id}) api_manila.share_network_get.assert_called_once_with( mock.ANY, share_net.id) def test_detail_view_with_exception(self): url = reverse('horizon:admin:share_networks:share_network_detail', args=[test_data.active_share_network.id]) self.mock_object( api_manila, "share_network_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_network_get.assert_called_once_with( mock.ANY, test_data.active_share_network.id) def test_delete_share_network(self): share_network = test_data.inactive_share_network formData = {'action': 'share_networks__delete__%s' % share_network.id} self.mock_object(api_manila, "share_network_delete") self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=[ test_data.active_share_network, test_data.inactive_share_network])) res = self.client.post(INDEX_URL, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_keystone.tenant_list.assert_called_once_with(mock.ANY) api_manila.share_network_delete.assert_called_once_with( mock.ANY, share_network.id) api_manila.share_network_list.assert_called_once_with( mock.ANY, detailed=True, search_opts={'all_tenants': True}) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_servers/0000775000175000017500000000000000000000000024645 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_servers/__init__.py0000664000175000017500000000000000000000000026744 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_servers/tests.py0000664000175000017500000001243400000000000026365 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from horizon import exceptions as horizon_exceptions from openstack_dashboard.api import keystone as api_keystone from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:admin:share_servers:index') class ShareServerTests(test.BaseAdminViewTests): def test_list_share_servers(self): share_servers = [ test_data.share_server, test_data.share_server_errored, ] projects = [ type('FakeProject', (object, ), {'id': s.project_id, 'name': '%s_name' % s.project_id}) for s in share_servers ] projects_dict = {p.id: p for p in projects} self.mock_object( api_manila, "share_server_list", mock.Mock(return_value=share_servers)) self.mock_object( api_manila, "share_list", mock.Mock(side_effect=[ [], [test_data.share], [test_data.nameless_share]])) self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(projects, None))) res = self.client.get(INDEX_URL) self.assertContains(res, "

Share Servers

") for share_server in share_servers: self.assertContains( res, '%s' % ( share_server.id, share_server.id), 1, 200) self.assertContains(res, share_server.host, 1, 200) self.assertContains( res, projects_dict[share_server.project_id].name, 1, 200) self.assertContains( res, '%s' % ( share_server.share_network_id, share_server.share_network), 1, 200) api_manila.share_list.assert_has_calls([ mock.call( mock.ANY, search_opts={'share_server_id': share_server.id}) for share_server in share_servers ]) api_manila.share_server_list.assert_called_once_with(mock.ANY) self.assertEqual(1, api_keystone.tenant_list.call_count) def test_detail_view_share_server(self): share_server = test_data.share_server shares = [test_data.share, test_data.nameless_share] url = reverse( 'horizon:admin:share_servers:share_server_detail', args=[share_server.id]) self.mock_object( api_manila, "share_server_get", mock.Mock(return_value=share_server)) self.mock_object( api_manila, "share_list", mock.Mock(return_value=shares)) res = self.client.get(url) self.assertContains( res, "

Share Server Details: %s

" % share_server.id, 1, 200) self.assertContains(res, "
%s
" % share_server.id, 1, 200) self.assertContains(res, "
Active
", 1, 200) self.assertContains(res, "
%s
" % share_server.host, 1, 200) self.assertContains( res, "
%s
" % ( share_server.share_network_id, share_server.share_network_name), 1, 200) self.assertContains( res, "
%s
" % ( shares[0].id, shares[0].name), 1, 200) self.assertContains( res, "
%s
" % ( shares[1].id, shares[1].id), 1, 200) for k, v in share_server.backend_details.items(): self.assertContains(res, "
%s
" % k) self.assertContains(res, "
%s
" % v) self.assertNoMessages() api_manila.share_server_get.assert_called_once_with( mock.ANY, share_server.id) api_manila.share_list.assert_called_once_with( mock.ANY, search_opts={"share_server_id": share_server.id}) def test_detail_view_share_server_with_exception(self): share_server = test_data.share_server url = reverse('horizon:admin:share_servers:share_server_detail', args=[share_server.id]) self.mock_object( api_manila, "share_server_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_server_get.assert_called_once_with( mock.ANY, share_server.id) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_snapshots/0000775000175000017500000000000000000000000025176 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_snapshots/__init__.py0000664000175000017500000000000000000000000027275 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_snapshots/tests.py0000664000175000017500000001514600000000000026721 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from horizon import exceptions as horizon_exceptions from openstack_dashboard.api import keystone as api_keystone from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from manila_ui.tests.test_data import keystone_data INDEX_URL = reverse('horizon:admin:share_snapshots:index') class SnapshotsTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(keystone_data.projects, None))) # Reset taken list of projects to avoid test interference utils.PROJECTS = {} def test_detail_view(self): snapshot = test_data.snapshot share = test_data.share url = reverse('horizon:admin:share_snapshots:share_snapshot_detail', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) res = self.client.get(url) self.assertContains(res, "

Snapshot Details: %s

" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.id, 1, 200) self.assertContains(res, "
%s
" % (snapshot.share_id, share.name), 1, 200) self.assertContains(res, "
%s GiB
" % snapshot.size, 1, 200) self.assertNoMessages() api_manila.share_get.assert_called_once_with(mock.ANY, share.id) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) def test_detail_view_with_mount_support(self): snapshot = test_data.snapshot_mount_support rules = [test_data.ip_rule, test_data.user_rule, test_data.cephx_rule] export_locations = test_data.admin_snapshot_export_locations share = test_data.share_mount_snapshot url = reverse('horizon:admin:share_snapshots:share_snapshot_detail', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) self.mock_object( api_manila, "share_snapshot_rules_list", mock.Mock( return_value=rules)) self.mock_object( api_manila, "share_snap_export_location_list", mock.Mock( return_value=export_locations)) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) res = self.client.get(url) self.assertContains(res, "

Snapshot Details: %s

" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.id, 1, 200) self.assertContains(res, "
%s
" % (snapshot.share_id, share.name), 1, 200) self.assertContains(res, "
%s GiB
" % snapshot.size, 1, 200) for el in export_locations: self.assertContains(res, "value=\"%s\"" % el.path, 1, 200) self.assertContains( res, "
Is admin only: %s
" % el.is_admin_only, 1, 200) self.assertContains( res, ("
Snapshot Replica ID: %s
" % el.share_snapshot_instance_id), 1, 200) for rule in rules: self.assertContains(res, "
%s
" % rule.access_type, 1, 200) self.assertContains( res, "
Access to: %s
" % rule.access_to, 1, 200) self.assertContains( res, "
Status: active
", len(rules), 200) self.assertNoMessages() api_manila.share_get.assert_called_once_with(mock.ANY, share.id) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) api_manila.share_snapshot_rules_list.assert_called_once_with( mock.ANY, snapshot.id) api_manila.share_snap_export_location_list.assert_called_once_with( mock.ANY, snapshot) def test_detail_view_with_exception(self): url = reverse('horizon:admin:share_snapshots:share_snapshot_detail', args=[test_data.snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, test_data.snapshot.id) def test_delete_snapshot(self): share = test_data.share snapshot = test_data.snapshot formData = {'action': 'share_snapshots__delete__%s' % snapshot.id} self.mock_object(api_manila, "share_snapshot_delete") self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[snapshot])) self.mock_object( api_manila, "share_list", mock.Mock(return_value=[share])) res = self.client.post(INDEX_URL, formData) api_keystone.tenant_list.assert_called_once_with(mock.ANY) api_manila.share_snapshot_delete.assert_called_once_with( mock.ANY, test_data.snapshot.id) api_manila.share_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) api_manila.share_list.assert_called_once_with(mock.ANY) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_types/0000775000175000017500000000000000000000000024320 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_types/__init__.py0000664000175000017500000000000000000000000026417 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_types/test_forms.py0000664000175000017500000002610300000000000027061 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from io import BytesIO import ddt from django.core.handlers import wsgi from django.core.handlers.wsgi import LimitedStream from django import forms as django_forms from horizon import forms as horizon_forms from unittest import mock from manila_ui.dashboards.admin.share_types import forms from manila_ui.tests import helpers as base @ddt.ddt class ManilaDashboardsAdminSharesUpdateShareTypeFormTests(base.APITestCase): def setUp(self): super(self.__class__, self).setUp() stream = LimitedStream(BytesIO(b"test"), 2) FAKE_ENVIRON = {'REQUEST_METHOD': 'GET', 'wsgi.input': stream} self.request = wsgi.WSGIRequest(FAKE_ENVIRON) def _get_form(self, initial): kwargs = { 'prefix': None, 'initial': initial, } return forms.UpdateShareType(self.request, **kwargs) @ddt.data( ({}, []), ({'foo': 'bar', 'quuz': 'zaab'}, ["foo=bar\r\n", "quuz=zaab\r\n"]), ) @ddt.unpack def test___init__(self, extra_specs_dict_input, extra_specs_str_output): form = self._get_form({'extra_specs': extra_specs_dict_input}) for expected_extra_spec in extra_specs_str_output: self.assertIn(expected_extra_spec, form.initial['extra_specs']) self.assertIn('extra_specs', list(form.fields.keys())) self.assertIsInstance(form.fields['extra_specs'], horizon_forms.CharField) @mock.patch('horizon.messages.success') def test_handle_success_no_changes(self, mock_horizon_messages_success): initial = {'id': 'fake_id', 'name': 'fake_name', 'extra_specs': {}} form = self._get_form(initial) data = {'extra_specs': ''} result = form.handle(self.request, data) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( mock.ANY, mock.ANY) @mock.patch('horizon.messages.success') def test_handle_success_only_set(self, mock_horizon_messages_success): initial = { 'id': 'fake_id', 'name': 'fake_name', 'extra_specs': {'foo': 'bar'} } form = self._get_form(initial) data = {'extra_specs': 'foo=bar\r\n'} result = form.handle(self.request, data) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( mock.ANY, mock.ANY) self.manilaclient.share_types.get.assert_called_with( initial['id']) self.manilaclient.share_types.get.return_value.set_keys.\ assert_called_once_with({'foo': 'bar'}) self.assertFalse( self.manilaclient.share_types.get.return_value.unset_keys.called) @mock.patch('horizon.messages.success') def test_handle_success_only_unset(self, mock_horizon_messages_success): initial = { 'id': 'fake_id', 'name': 'fake_name', 'extra_specs': {'foo': 'bar'} } form = self._get_form(initial) data = {'extra_specs': 'foo\r\n'} share_types_get = self.manilaclient.share_types.get share_types_get.return_value.get_keys.return_value = { 'foo': 'bar', 'quuz': 'zaab'} result = form.handle(self.request, data) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( mock.ANY, mock.ANY) self.manilaclient.share_types.get.assert_has_calls([ mock.call(initial['id'])]) share_types_get.return_value.get_keys.assert_called_once_with() self.assertFalse(share_types_get.return_value.set_keys.called) share_types_get.return_value.unset_keys.assert_called_once_with( {'foo'}) @mock.patch('horizon.messages.success') def test_handle_success_set_and_unset(self, mock_horizon_messages_success): initial = { 'id': 'fake_id', 'name': 'fake_name', 'extra_specs': {'foo': 'bar'} } form = self._get_form(initial) data = {'extra_specs': 'foo\r\nquuz=zaab'} share_types_get = self.manilaclient.share_types.get share_types_get.return_value.get_keys.return_value = {'foo': 'bar'} result = form.handle(self.request, data) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( mock.ANY, mock.ANY) self.manilaclient.share_types.get.assert_has_calls([ mock.call(initial['id'])]) share_types_get.return_value.get_keys.assert_called_once_with() share_types_get.return_value.set_keys.assert_called_once_with( {'quuz': 'zaab'}) share_types_get.return_value.unset_keys.assert_called_once_with( {'foo'}) def test_handle_validation_error(self): initial = {'id': 'fake_id', 'name': 'fake_name', 'extra_specs': {}} form = self._get_form(initial) form.api_error = mock.Mock() data = {'extra_specs': 'a b'} result = form.handle(self.request, data) self.assertFalse(result) form.api_error.assert_called_once_with(mock.ANY) @mock.patch('horizon.exceptions.handle') def test_handle_other_exception(self, mock_horizon_exceptions_handle): django_forms.ValidationError initial = {'id': 'fake_id', 'name': 'fake_name', 'extra_specs': {}} form = self._get_form(initial) data = {'extra_specs': None} result = form.handle(self.request, data) self.assertFalse(result) mock_horizon_exceptions_handle.assert_called_once_with( self.request, mock.ANY) @ddt.data( ('name_updated_1', 'description_updated', True), ('name_updated_2', 'description_updated', False), ('name_updated_3', None, True), ) @ddt.unpack @mock.patch('horizon.messages.success') def test_update_share_type_name_description_public( self, name, description, is_public, mock_horizon_messages_success): initial = { 'id': 'fake_id', 'name': 'fake_name', 'description': 'fake_description', 'is_public': True, 'extra_specs': {} } form = self._get_form(initial) data = { 'name': name, 'description': description, 'is_public': is_public, 'extra_specs': '', } result = form.handle(self.request, data) self.assertIs(True, result) mock_horizon_messages_success.assert_called_once_with( mock.ANY, mock.ANY) self.manilaclient.share_types.get.assert_called_once_with( initial['id']) self.manilaclient.share_types.get.return_value.update.\ assert_called_once_with(name=data['name'], description=data['description'], is_public=data['is_public']) @ddt.ddt class ManilaDashboardsAdminSharesCreateShareTypeFormTests(base.APITestCase): def setUp(self): super(self.__class__, self).setUp() stream = LimitedStream(BytesIO(b"test"), 2) FAKE_ENVIRON = {'REQUEST_METHOD': 'GET', 'wsgi.input': stream} self.request = wsgi.WSGIRequest(FAKE_ENVIRON) def _get_form(self, **kwargs): return forms.CreateShareType(self.request, **kwargs) @mock.patch('horizon.messages.success') def test_create_share_type(self, mock_horizon_messages_success): form = self._get_form() data = { 'extra_specs': '', 'is_public': False, 'spec_driver_handles_share_servers': 'True', 'name': 'share', 'description': '' } result = form.handle(self.request, data) self.assertTrue(result) self.manilaclient.share_types.create.assert_called_once_with( name=data['name'], spec_driver_handles_share_servers='true', description=data['description'], is_public=data["is_public"]) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) @mock.patch('horizon.messages.success') def test_create_share_type_with_extra_specs_and_description( self, mock_horizon_messages_success): form = self._get_form() data = {'extra_specs': 'a=b \n c=d', 'is_public': False, 'spec_driver_handles_share_servers': 'True', 'description': 'st_description', 'name': 'share'} result = form.handle(self.request, data) self.assertTrue(result) set_keys = self.manilaclient.share_types.get.return_value.set_keys set_keys.assert_called_once_with( {'a': 'b', 'c': 'd'}) self.manilaclient.share_types.create.assert_called_once_with( name=data['name'], spec_driver_handles_share_servers='true', description=data['description'], is_public=data["is_public"]) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) @ddt.data(True, False) @mock.patch('horizon.messages.success') def test_public_share_type_creation(self, enable_public_share_type_creation, mock_horizon_messages_success): with self.settings(OPENSTACK_MANILA_FEATURES={ 'enable_public_share_type_creation': enable_public_share_type_creation}): form = self._get_form() data = { 'extra_specs': '', 'is_public': enable_public_share_type_creation, 'spec_driver_handles_share_servers': 'True', 'name': 'share', 'description': '', } result = form.handle(self.request, data) self.assertTrue(result) self.assertEqual( enable_public_share_type_creation, form.enable_public_share_type_creation) if enable_public_share_type_creation: self.assertIn("is_public", form.fields) self.assertTrue(form.fields["is_public"]) else: self.assertNotIn("is_public", form.fields) self.manilaclient.share_types.create.assert_called_once_with( name=data['name'], spec_driver_handles_share_servers='true', description=data['description'], is_public=enable_public_share_type_creation) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/share_types/tests.py0000664000175000017500000000756600000000000026052 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from openstack_dashboard.api import keystone as api_keystone from openstack_dashboard.api import neutron as api_neutron from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from manila_ui.tests.test_data import keystone_data INDEX_URL = reverse('horizon:admin:share_types:index') class ShareTypeTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.share_type = test_data.share_type self.url = reverse('horizon:admin:share_types:update_type', args=[self.share_type.id]) self.mock_object( api_manila, "share_type_get", mock.Mock(return_value=self.share_type)) self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(keystone_data.projects, None))) self.mock_object( api_neutron, "is_service_enabled", mock.Mock(return_value=[True])) # Reset taken list of projects to avoid test interference utils.PROJECTS = {} def test_create_share_type(self): url = reverse('horizon:admin:share_types:create_type') data = { 'is_public': True, 'name': 'my_share_type', 'description': 'share_type_description', 'spec_driver_handles_share_servers': 'False' } form_data = data.copy() form_data['spec_driver_handles_share_servers'] = 'false' self.mock_object(api_manila, "share_type_create") res = self.client.post(url, data) api_manila.share_type_create.assert_called_once_with( mock.ANY, form_data['name'], form_data['spec_driver_handles_share_servers'], description=form_data['description'], is_public=form_data['is_public']) self.assertRedirectsNoFollow(res, INDEX_URL) def test_update_share_type_get(self): res = self.client.get(self.url) api_manila.share_type_get.assert_called_once_with( mock.ANY, self.share_type.id) self.assertNoMessages() self.assertTemplateUsed(res, 'admin/share_types/update.html') def test_update_share_type_post(self): data = { 'name': 'share_type_update', 'description': 'share_type_description', 'is_public': True, 'extra_specs': 'fork_key=fork_val' } form_data = { 'name': 'share_type_update', 'description': 'share_type_description', 'is_public': True, 'extra_specs': {'fork_key': 'fork_val'}, } self.mock_object(api_manila, "share_type_set_extra_specs") self.mock_object(api_manila, "share_type_update") res = self.client.post(self.url, data) api_manila.share_type_set_extra_specs.assert_called_once_with( mock.ANY, self.share_type.id, form_data['extra_specs']) api_manila.share_type_update.assert_called_once_with( mock.ANY, self.share_type.id, data['name'], data['description'], data['is_public']) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/0000775000175000017500000000000000000000000023257 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/__init__.py0000664000175000017500000000000000000000000025356 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/replicas/0000775000175000017500000000000000000000000025061 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/replicas/__init__.py0000664000175000017500000000000000000000000027160 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/replicas/tests.py0000664000175000017500000003474500000000000026612 0ustar00zuulzuul00000000000000# Copyright (c) 2016 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ddt from django.urls import reverse from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from openstack_dashboard.api import neutron SHARE_INDEX_URL = reverse('horizon:admin:shares:index') @ddt.ddt class ReplicasTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.share = test_data.share self.share_replica = test_data.share_replica self.share_replica2 = test_data.share_replica2 self.mock_object( api_manila, "share_get", mock.Mock(return_value=self.share)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) def test_detail(self): url = reverse( "horizon:admin:shares:replica_detail", args=[self.share_replica.id]) export_locations = test_data.export_locations self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) self.mock_object( api_manila, "share_instance_export_location_list", mock.Mock(return_value=export_locations)) res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed(res, "admin/shares/replicas/detail.html") self.assertNoMessages() self.assertContains(res, "

Share Replica Overview", 1, 200) self.assertContains(res, ">%s" % self.share.id, 1, 200) self.assertContains(res, "
%s
" % self.share_replica.id, 1, 200) self.assertContains( res, "
%s
" % self.share.availability_zone, 1, 200) for el in export_locations: self.assertContains(res, "value=\"%s\"" % el.path, 1, 200) self.assertContains( res, "
Preferred: %s
" % el.preferred, 1, 200) self.assertContains( res, "
Is admin only: %s
" % el.is_admin_only, 1, 200) self.assertNoMessages() api_manila.share_replica_get.assert_called_once_with( mock.ANY, self.share_replica.id) api_manila.share_instance_export_location_list.assert_called_once_with( mock.ANY, self.share_replica.id) def test_detail_not_found(self): url = reverse("horizon:admin:shares:replica_detail", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock( side_effect=Exception("Fake replica NotFound exception"))) self.mock_object(api_manila, "share_instance_export_location_list") res = self.client.get(url) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, SHARE_INDEX_URL) self.assertTemplateNotUsed(res, "admin/shares/replicas/detail.html") api_manila.share_replica_get.assert_called_once_with( mock.ANY, self.share_replica.id) self.assertFalse(api_manila.share_instance_export_location_list.called) def test_list(self): self.mock_object( api_manila, "share_replica_list", mock.Mock(return_value=[self.share_replica])) url = reverse( "horizon:admin:shares:manage_replicas", args=[self.share.id]) res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed( res, "admin/shares/replicas/manage_replicas.html") api_manila.share_get.assert_called_with(mock.ANY, self.share.id) api_manila.share_replica_list.assert_called_with( mock.ANY, self.share.id) def test_list_exception(self): self.mock_object( api_manila, "share_replica_list", mock.Mock(side_effect=Exception("Fake exception"))) url = reverse( "horizon:admin:shares:manage_replicas", args=[self.share.id]) res = self.client.get(url) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, SHARE_INDEX_URL) self.assertTemplateNotUsed( res, "admin/shares/replicas/manage_replicas.html") api_manila.share_replica_list.assert_called_with( mock.ANY, self.share.id) @ddt.data( ([test_data.share_replica], test_data.share_replica.id, None), ([test_data.share_replica], test_data.share_replica.id, 'dr'), ([test_data.share_replica], test_data.share_replica.id, 'readable'), ([test_data.share_replica], test_data.share_replica.id, 'writable'), ([test_data.share_replica, test_data.share_replica2], test_data.share_replica.id, 'dr'), ([test_data.share_replica, test_data.share_replica2], test_data.share_replica.id, 'readable'), ) @ddt.unpack def test_delete_not_allowed(self, replica_list, replica_id, replication_type): share = test_data.share share.replication_type = replication_type formData = {"action": "replicas__delete__%s" % replica_id} self.mock_object(api_manila, "share_replica_delete") self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_replica_list", mock.Mock(return_value=replica_list)) url = reverse( "horizon:admin:shares:manage_replicas", args=[share.id]) res = self.client.post(url, formData) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, url) api_manila.share_replica_list.assert_called_with(mock.ANY, share.id) self.assertFalse(api_manila.share_replica_delete.called) @ddt.data( ([test_data.share_replica, test_data.share_replica2], test_data.share_replica2.id, 'dr'), ([test_data.share_replica, test_data.share_replica2], test_data.share_replica2.id, 'readable'), ([test_data.share_replica, test_data.share_replica3], test_data.share_replica.id, 'writable'), ([test_data.share_replica, test_data.share_replica3], test_data.share_replica3.id, 'writable'), ) @ddt.unpack def test_delete_allowed(self, replica_list, replica_id, replication_type): share = test_data.share share.replication_type = replication_type formData = {"action": "replicas__delete__%s" % replica_id} self.mock_object(api_manila, "share_replica_delete") self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_replica_list", mock.Mock(return_value=replica_list)) url = reverse( "horizon:admin:shares:manage_replicas", args=[share.id]) res = self.client.post(url, formData) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, url) api_manila.share_replica_list.assert_called_with(mock.ANY, share.id) api_manila.share_replica_delete.assert_called_with( mock.ANY, replica_id) def test_resync_replica_get(self): url = reverse( "horizon:admin:shares:resync_replica", args=[self.share_replica.id]) self.mock_object(api_manila, "share_replica_get") self.mock_object(api_manila, "share_replica_resync") res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed( res, "admin/shares/replicas/resync_replica.html") self.assertFalse(api_manila.share_replica_get.called) self.assertFalse(api_manila.share_replica_resync.called) def _resync_post(self): url = reverse( "horizon:admin:shares:resync_replica", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) formData = { "method": "ResyncReplicaForm", "replica_id": self.share_replica.id, } res = self.client.post(url, formData) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed( res, "admin/shares/replicas/resync_replica.html") api_manila.share_replica_resync.assert_called_once_with( mock.ANY, self.share_replica) return res def test_resync_post(self): self.mock_object(api_manila, "share_replica_resync") res = self._resync_post() self.assertRedirectsNoFollow( res, reverse("horizon:admin:shares:manage_replicas", args=[self.share.id])) def test_resync_post_error(self): self.mock_object( api_manila, "share_replica_resync", mock.Mock(side_effect=Exception("Fake exception"))) res = self._resync_post() self.assertRedirectsNoFollow( res, reverse("horizon:admin:shares:index")) def test_reset_replica_status_get(self): url = reverse( "horizon:admin:shares:reset_replica_status", args=[self.share_replica.id]) self.mock_object(api_manila, "share_replica_get") self.mock_object(api_manila, "share_replica_reset_status") res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed( res, "admin/shares/replicas/reset_replica_status.html") self.assertFalse(api_manila.share_replica_get.called) self.assertFalse(api_manila.share_replica_reset_status.called) @ddt.data("available", "creating", "deleting", "error") def test_reset_replica_status_post(self, status): url = reverse( "horizon:admin:shares:reset_replica_status", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) self.mock_object(api_manila, "share_replica_reset_status") form_data = {"replica_status": status} res = self.client.post(url, form_data) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed( res, "admin/shares/replicas/reset_replica_status.html") api_manila.share_replica_reset_status.assert_called_once_with( mock.ANY, self.share_replica, status) self.assertRedirectsNoFollow( res, reverse("horizon:admin:shares:manage_replicas", args=[self.share.id])) def test_reset_replica_status_error(self): status = "error" url = reverse( "horizon:admin:shares:reset_replica_status", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) self.mock_object( api_manila, "share_replica_reset_status", mock.Mock(side_effect=Exception("Fake exception"))) form_data = {"replica_status": status} res = self.client.post(url, form_data) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed( res, "admin/shares/replicas/reset_replica_status.html") api_manila.share_replica_reset_status.assert_called_once_with( mock.ANY, self.share_replica, status) self.assertRedirectsNoFollow( res, reverse("horizon:admin:shares:index")) def test_reset_replica_state_get(self): url = reverse( "horizon:admin:shares:reset_replica_state", args=[self.share_replica.id]) self.mock_object(api_manila, "share_replica_get") self.mock_object(api_manila, "share_replica_reset_state") res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed( res, "admin/shares/replicas/reset_replica_state.html") self.assertFalse(api_manila.share_replica_get.called) self.assertFalse(api_manila.share_replica_reset_state.called) @ddt.data("active", "in_sync", "out_of_sync", "error") def test_reset_replica_state_post(self, state): url = reverse( "horizon:admin:shares:reset_replica_state", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) self.mock_object(api_manila, "share_replica_reset_state") form_data = {"replica_state": state} res = self.client.post(url, form_data) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed( res, "admin/shares/replicas/reset_replica_state.html") api_manila.share_replica_reset_state.assert_called_once_with( mock.ANY, self.share_replica, state) self.assertRedirectsNoFollow( res, reverse("horizon:admin:shares:manage_replicas", args=[self.share.id])) def test_reset_replica_state_error(self): state = "error" url = reverse( "horizon:admin:shares:reset_replica_state", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) self.mock_object( api_manila, "share_replica_reset_state", mock.Mock(side_effect=Exception("Fake exception"))) form_data = {"replica_state": state} res = self.client.post(url, form_data) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed( res, "admin/shares/replicas/reset_replica_state.html") api_manila.share_replica_reset_state.assert_called_once_with( mock.ANY, self.share_replica, state) self.assertRedirectsNoFollow( res, reverse("horizon:admin:shares:index")) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/test_forms.py0000664000175000017500000001042200000000000026015 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from io import BytesIO from django.core.handlers import wsgi from django.core.handlers.wsgi import LimitedStream from unittest import mock from manila_ui.api import manila as api from manila_ui.dashboards.admin.shares import forms from manila_ui.tests import helpers as base class ManilaDashboardsAdminMigrationFormTests(base.APITestCase): def setUp(self): super(self.__class__, self).setUp() stream = LimitedStream(BytesIO(b"test"), 2) FAKE_ENVIRON = {'REQUEST_METHOD': 'GET', 'wsgi.input': stream} self.request = wsgi.WSGIRequest(FAKE_ENVIRON) def _get_initial(self): initial = {'name': 'fake_name', 'share_id': 'fake_id'} kwargs = { 'prefix': None, 'initial': initial, } return kwargs @mock.patch('horizon.messages.success') def test_migration_start(self, mock_horizon_messages_success): self.mock_object( api, "share_network_list", mock.Mock(return_value=[base.FakeEntity('sn1_id', 'sn1_name'), base.FakeEntity('sn2_id', 'sn2_name')])) self.mock_object( api, "share_type_list", mock.Mock(return_value=[base.FakeEntity('st1_id', 'st1_name'), base.FakeEntity('st2_id', 'st2_name')])) self.mock_object( api, "pool_list", mock.Mock(return_value=[base.FakeEntity('ubuntu@beta#BETA', 'ubuntu@beta#BETA'), base.FakeEntity('ubuntu@alpha#ALPHA', 'ubuntu@alpha#ALPHA')])) form = forms.MigrationStart(self.request, **self._get_initial()) data = { 'force_host_assisted_migration': False, 'writable': True, 'preserve_metadata': True, 'preserve_snapshots': True, 'nondisruptive': True, 'new_share_network': 'fake_net_id', 'new_share_type': 'fake_type_id', 'host': 'fake_host', } result = form.handle(self.request, data) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) api.share_network_list.assert_called_once_with(mock.ANY) api.share_type_list.assert_called_once_with(mock.ANY) api.pool_list.assert_called_once_with(mock.ANY) @mock.patch('horizon.messages.success') def test_migration_complete(self, mock_horizon_messages_success): form = forms.MigrationComplete(self.request, **self._get_initial()) result = form.handle(self.request, {}) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) @mock.patch('horizon.messages.success') def test_migration_cancel(self, mock_horizon_messages_success): form = forms.MigrationCancel(self.request, **self._get_initial()) result = form.handle(self.request, {}) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) @mock.patch('horizon.messages.success') def test_migration_get_progress(self, mock_horizon_messages_success): result = ({'Response': 200}, {'total_progress': 25}) self.mock_object(api, 'migration_get_progress', mock.Mock(return_value=result)) form = forms.MigrationGetProgress(self.request, **self._get_initial()) result = form.handle(self.request, {}) self.assertTrue(result) mock_horizon_messages_success.assert_called_once_with( self.request, mock.ANY) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/shares/tests.py0000664000175000017500000002446300000000000025004 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # Copyright (c) 2015 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ddt from django.urls import reverse from openstack_dashboard.api import keystone as api_keystone from openstack_dashboard.api import neutron as api_neutron from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from manila_ui.tests.test_data import keystone_data INDEX_URL = reverse('horizon:admin:shares:index') @ddt.ddt class SharesTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.mock_object(utils.timeutils, 'now', mock.Mock(return_value=1)) self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(keystone_data.projects, None))) # Reset taken list of projects to avoid test interference utils.PROJECTS = {} def test_index(self): snaps = [test_data.snapshot] shares = [test_data.share, test_data.nameless_share, test_data.other_share] utils.timeutils.now.side_effect = [4] + [24 + i for i in range(4)] self.mock_object( api_manila, "share_list", mock.Mock(return_value=shares)) self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=snaps)) self.mock_object( api_neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(INDEX_URL) self.assertTemplateUsed(res, 'admin/shares/index.html') self.assertEqual(res.status_code, 200) api_manila.share_list.assert_called_with( mock.ANY, search_opts={'all_tenants': True}) api_manila.share_snapshot_list.assert_called_with( mock.ANY, detailed=True, search_opts={'all_tenants': True}) api_keystone.tenant_list.assert_called_once_with(mock.ANY) def test_delete_share(self): url = reverse('horizon:admin:shares:index') share = test_data.share formData = {'action': 'shares__delete__%s' % share.id} self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[])) self.mock_object(api_manila, "share_delete") self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_list", mock.Mock(return_value=[share])) res = self.client.post(url, formData) api_keystone.tenant_list.assert_called_once_with(mock.ANY) api_manila.share_delete.assert_called_once_with( mock.ANY, share.id, share_group_id=share.share_group_id) api_manila.share_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) api_manila.share_snapshot_list.assert_called_once_with( mock.ANY, detailed=True, search_opts={'all_tenants': True}) self.assertRedirectsNoFollow(res, INDEX_URL) @ddt.data(None, Exception('fake')) def test_migration_start_post(self, exc): share = test_data.share url = reverse('horizon:admin:shares:migration_start', args=[share.id]) sn_choices = [test.FakeEntity('sn1_id', 'sn1_name'), test.FakeEntity('sn2_id', 'sn2_name')] st_choices = [test.FakeEntity('st1_id', 'st1_name'), test.FakeEntity('st2_id', 'st2_name')] dest_choices = [ test.FakeEntity('ubuntu@beta#BETA', 'ubuntu@beta#BETA'), test.FakeEntity('ubuntu@alpha#ALPHA', 'ubuntu@alpha#ALPHA') ] formData = { 'share_id': share.id, 'name': share.name, 'host': 'ubuntu@alpha#ALPHA', 'writable': True, 'preserve_metadata': True, 'preserve_snapshots': True, 'force_host_assisted_migration': True, 'nondisruptive': True, 'new_share_network': 'sn2_id', 'new_share_type': 'st2_id', } self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( api_manila, "migration_start", mock.Mock(side_effect=exc)) self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=sn_choices)) self.mock_object( api_manila, "share_type_list", mock.Mock(return_value=st_choices)) self.mock_object( api_manila, "pool_list", mock.Mock(return_value=dest_choices)) res = self.client.post(url, formData) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) api_manila.migration_start.assert_called_once_with( mock.ANY, formData['share_id'], dest_host=formData['host'], force_host_assisted_migration=( formData['force_host_assisted_migration']), writable=formData['writable'], preserve_metadata=formData['preserve_metadata'], preserve_snapshots=formData['preserve_snapshots'], nondisruptive=formData['nondisruptive'], new_share_network_id=formData['new_share_network'], new_share_type_id=formData['new_share_type']) api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_type_list.assert_called_once_with(mock.ANY) api_manila.pool_list.assert_called_once_with(mock.ANY) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed(res, 'admin/shares/migration_start.html') self.assertRedirectsNoFollow(res, INDEX_URL) @ddt.data('migration_start', 'migration_cancel', 'migration_complete', 'migration_get_progress') def test_migration_forms_open_form_successfully(self, method): share = test_data.share url = reverse('horizon:admin:shares:' + method, args=[share.id]) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object(api_manila, method) if method == 'migration_start': self.mock_object( api_manila, "share_network_list", mock.Mock( return_value=[test.FakeEntity('sn1_id', 'sn1_name'), test.FakeEntity('sn2_id', 'sn2_name')])) self.mock_object( api_manila, "share_type_list", mock.Mock( return_value=[test.FakeEntity('st1_id', 'st1_name'), test.FakeEntity('st2_id', 'st2_name')])) self.mock_object( api_manila, "pool_list", mock.Mock(return_value=[test.FakeEntity('ubuntu@beta#BETA', 'ubuntu@beta#BETA'), test.FakeEntity('ubuntu@alpha#ALPHA', 'ubuntu@alpha#ALPHA') ])) res = self.client.get(url) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) self.assertFalse(getattr(api_manila, method).called) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, 'admin/shares/' + method + '.html') if method == 'migration_start': api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_type_list.assert_called_once_with(mock.ANY) api_manila.pool_list.assert_called_once_with(mock.ANY) @ddt.data('migration_start', 'migration_cancel', 'migration_complete', 'migration_get_progress') def test_migration_start_get_share_exception(self, method): share = test_data.share url = reverse('horizon:admin:shares:' + method, args=[share.id]) self.mock_object( api_manila, "share_get", mock.Mock(side_effect=Exception('fake'))) self.mock_object(api_manila, method) res = self.client.get(url) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) self.assertFalse(getattr(api_manila, method).called) self.assertEqual(res.status_code, 302) self.assertTemplateNotUsed(res, 'admin/shares/' + method + '.html') @ddt.data({'method': 'migration_complete', 'exc': None}, {'method': 'migration_complete', 'exc': Exception('fake')}, {'method': 'migration_cancel', 'exc': None}, {'method': 'migration_cancel', 'exc': Exception('fake')}, {'method': 'migration_get_progress', 'exc': {'response': 200, 'total_progress': 25}}, {'method': 'migration_get_progress', 'exc': Exception('fake')}) @ddt.unpack def test_migration_forms_post(self, exc, method): share = test_data.share url = reverse('horizon:admin:shares:' + method, args=[share.id]) formData = { 'share_id': share.id, 'name': share.name, } self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object(api_manila, method, mock.Mock( side_effect=exc)) res = self.client.post(url, formData) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) getattr(api_manila, method).assert_called_once_with( mock.ANY, formData['share_id']) status_code = 200 if exc else 302 self.assertEqual(res.status_code, status_code) if not exc: self.assertTemplateNotUsed( res, 'admin/shares/' + method + '.html') self.assertRedirectsNoFollow(res, INDEX_URL) else: self.assertTemplateUsed( res, 'admin/shares/' + method + '.html') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/user_messages/0000775000175000017500000000000000000000000024637 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/user_messages/__init__.py0000664000175000017500000000000000000000000026736 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/admin/user_messages/tests.py0000664000175000017500000001065400000000000026361 0ustar00zuulzuul00000000000000# Copyright 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ddt from django.urls import reverse from openstack_dashboard.api import keystone as api_keystone from unittest import mock from horizon import exceptions as horizon_exceptions from manila_ui.api import manila as api_manila from manila_ui.dashboards.admin import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test from manila_ui.tests.test_data import keystone_data INDEX_URL = reverse('horizon:admin:user_messages:index') @ddt.ddt class UserMessagesViewTests(test.BaseAdminViewTests): def setUp(self): super(self.__class__, self).setUp() self.mock_object( api_keystone, "tenant_list", mock.Mock(return_value=(keystone_data.projects, None))) # Reset taken list of projects to avoid test interference utils.PROJECTS = {} @ddt.data(None, Exception('fake')) def test_view(self, exc): message_1 = test_data.fake_message_1 message_2 = test_data.fake_message_2 message_3 = test_data.fake_message_3 fake_message_list = [message_1, message_2, message_3] url = reverse('horizon:admin:user_messages:index') self.mock_object( api_manila, "messages_list", mock.Mock(side_effect=exc, return_value=fake_message_list)) self.client.get(url) self.assertNoMessages() api_manila.messages_list.assert_called_once_with(mock.ANY) @ddt.data(None, Exception('fake')) def test_delete_message(self, exc): message = test_data.fake_message_1 formData = {'action': 'user_messages__delete__%s' % message.id} self.mock_object(api_manila, "messages_delete", mock.Mock(side_effect=exc)) self.mock_object( api_manila, "messages_list", mock.Mock(return_value=[message])) res = self.client.post(INDEX_URL, formData) self.assertEqual(res.status_code, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.messages_list.assert_called_once_with(mock.ANY) api_manila.messages_delete.assert_called_once_with( mock.ANY, test_data.fake_message_1.id) @ddt.ddt class UserMessagesDetailViewTests(test.BaseAdminViewTests): def test_detail_view(self): message = test_data.fake_message_1 url = reverse('horizon:admin:user_messages:user_messages_detail', args=[message.id]) self.mock_object( api_manila, "messages_get", mock.Mock(return_value=message)) res = self.client.get(url) self.assertContains(res, "

User Message Details: %s

" % message.id, 1, 200) self.assertContains(res, "
%s
" % message.id, 1, 200) self.assertContains(res, "
%s
" % message.action_id, 1, 200) self.assertContains(res, "
%s
" % message.user_message, 1, 200) self.assertContains(res, "
%s
" % message.message_level, 1, 200) self.assertContains(res, "
%s
" % message.resource_type, 1, 200) self.assertContains(res, "
%s
" % message.resource_id, 1, 200) self.assertContains(res, "
%s
" % message.request_id, 1, 200) self.assertNoMessages() api_manila.messages_get.assert_called_once_with( mock.ANY, message.id) def test_detail_view_with_exception(self): message = test_data.fake_message_1 url = reverse( 'horizon:admin:user_messages:user_messages_detail', args=[message.id]) self.mock_object( api_manila, "messages_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.messages_get.assert_called_once_with(mock.ANY, message.id) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/identity/0000775000175000017500000000000000000000000022533 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/identity/__init__.py0000664000175000017500000000000000000000000024632 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/identity/projects/0000775000175000017500000000000000000000000024364 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/identity/projects/__init__.py0000664000175000017500000000000000000000000026463 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/identity/projects/tests.py0000664000175000017500000000544300000000000026106 0ustar00zuulzuul00000000000000# (c) Copyright 2019 SUSE 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. from django.test.utils import override_settings from django.urls import reverse from horizon.workflows import views from openstack_dashboard.api import base from openstack_dashboard.usage import quotas from manila_ui.api import manila as manila_api from manila_ui.tests import helpers as manila_base_test class UpdateShareQuotaWorkflowTests(manila_base_test.BaseAdminViewTests): def setUp(self): super(UpdateShareQuotaWorkflowTests, self).setUp() self.id = "fake_id" # mock functions in manila.py self.mock_tenant_quota_get = ( self.mock_object(manila_api, "tenant_quota_get")) self.mock_tenant_quota_get.return_value = ( self._get_mock_share_quota_data()) # mock functions in quotas.py self.mock_object(quotas, "get_tenant_quota_data") self.mock_object(quotas, "get_disabled_quotas").return_value = set() def _get_mock_share_quota_data(self): quota_data = { 'shares': 24, 'gigabytes': 333, 'snapshots': 14, 'snapshot_gigabytes': 444, 'share_networks': 14 } return base.QuotaSet(quota_data) @override_settings(EXTRA_STEPS={ 'openstack_dashboard.dashboards.identity.projects.\ workflows.UpdateQuota': ( 'manila_ui.dashboards.identity.projects.workflows.UpdateShareQuota' )} ) def test_tenant_quota_get(self): tenant_id = 'fake_tenant_id' url = reverse('horizon:identity:projects:update_quotas', args=[tenant_id]) res = self.client.get(url) workflow = res.context['workflow'] self.assertTemplateUsed(res, views.WorkflowView.template_name) step = workflow.get_step("update_share_quotas") # Check step UI fields got the fields converted and data correct self.assertEqual(step.action.initial['project_id'], tenant_id) self.assertEqual(step.action.initial['shares'], 24) self.assertEqual(step.action.initial['share_gigabytes'], 333) self.assertEqual(step.action.initial['share_snapshot_gigabytes'], 444) self.assertEqual(step.action.initial['share_snapshots'], 14) self.assertEqual(step.action.initial['share_networks'], 14) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/0000775000175000017500000000000000000000000022350 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/__init__.py0000664000175000017500000000000000000000000024447 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/security_services/0000775000175000017500000000000000000000000026122 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/security_services/__init__.py0000664000175000017500000000000000000000000030221 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/security_services/tests.py0000664000175000017500000001523100000000000027640 0ustar00zuulzuul00000000000000# Copyright 2012 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Copyright 2012 Nebula, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from horizon import exceptions as horizon_exceptions from openstack_dashboard import api from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:security_services:index') class SecurityServicesViewTests(test.TestCase): def test_create_security_service(self): sec_service = test_data.sec_service formData = { 'name': 'new_sec_service', 'description': 'This is test security service', 'method': 'CreateForm', 'dns_ip': '1.2.3.4', 'ou': 'someOU', 'user': 'SomeUser', 'password': 'safepass', 'confirm_password': 'safepass', 'type': 'ldap', 'domain': 'TEST', 'server': 'testserver', } url = reverse( 'horizon:project:security_services:security_service_create') self.mock_object( api_manila, "security_service_create", mock.Mock(return_value=sec_service)) res = self.client.post(url, formData) del formData['method'] del formData['confirm_password'] api_manila.security_service_create.assert_called_with( mock.ANY, **formData) self.assertRedirectsNoFollow(res, INDEX_URL) def test_delete_security_service(self): security_service = test_data.sec_service formData = { 'action': 'security_services__delete__%s' % security_service.id, } self.mock_object(api_manila, "security_service_delete") self.mock_object( api_manila, "security_service_list", mock.Mock(return_value=[security_service])) res = self.client.post(INDEX_URL, formData) api_manila.security_service_list.assert_called_with(mock.ANY) api_manila.security_service_delete.assert_called_with( mock.ANY, security_service.id) self.assertRedirectsNoFollow(res, INDEX_URL) def test_detail_view(self): sec_service = test_data.sec_service self.mock_object( api_manila, "security_service_get", mock.Mock(return_value=sec_service)) url = reverse( 'horizon:project:security_services:security_service_detail', args=[sec_service.id]) res = self.client.get(url) self.assertContains(res, "

Security Service Details: %s

" % sec_service.name, 1, 200) self.assertContains(res, "
%s
" % sec_service.name, 1, 200) self.assertContains(res, "
%s
" % sec_service.id, 1, 200) self.assertContains(res, "
%s
" % sec_service.user, 1, 200) self.assertContains(res, "
%s
" % sec_service.server, 1, 200) self.assertContains(res, "
%s
" % sec_service.dns_ip, 1, 200) self.assertContains(res, "
%s
" % sec_service.ou, 1, 200) self.assertContains(res, "
%s
" % sec_service.domain, 1, 200) self.assertNoMessages() api_manila.security_service_get.assert_called_once_with( mock.ANY, sec_service.id) def test_detail_view_with_exception(self): url = reverse( 'horizon:project:security_services:security_service_detail', args=[test_data.sec_service.id]) self.mock_object( api_manila, "security_service_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.security_service_get.assert_called_once_with( mock.ANY, test_data.sec_service.id) def test_update_security_service_get(self): sec_service = test_data.sec_service url = reverse( 'horizon:project:security_services:security_service_update', args=[sec_service.id]) self.mock_object( api_manila, "security_service_get", mock.Mock(return_value=sec_service)) self.mock_object( api.neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) self.assertNoMessages() self.assertTemplateUsed( res, 'project/security_services/update.html') api_manila.security_service_get.assert_called_once_with( mock.ANY, sec_service.id) def test_update_security_service_post(self): sec_service = test_data.sec_service url = reverse( 'horizon:project:security_services:security_service_update', args=[sec_service.id]) formData = { 'method': 'UpdateForm', 'name': sec_service.name, 'description': sec_service.description, 'dns_ip': sec_service.dns_ip, 'ou': sec_service.ou, 'server': sec_service.server, 'domain': sec_service.domain, 'password': sec_service.password, 'confirm_password': sec_service.password, 'user': sec_service.user, } self.mock_object(api_manila, "security_service_update") self.mock_object( api_manila, "security_service_get", mock.Mock(return_value=sec_service)) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.security_service_get.assert_called_once_with( mock.ANY, sec_service.id) api_manila.security_service_update.assert_called_once_with( mock.ANY, sec_service.id, name=formData['name'], description=formData['description'], dns_ip=formData['dns_ip'], ou=formData['ou'], server=formData['server'], domain=formData['domain'], password=formData['password'], user=formData['user']) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_group_snapshots/0000775000175000017500000000000000000000000026770 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_group_snapshots/__init__.py0000664000175000017500000000000000000000000031067 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_group_snapshots/tests.py0000664000175000017500000002713700000000000030516 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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 ddt from django.urls import reverse from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:share_group_snapshots:index') @ddt.ddt class ShareGroupSnapshotTests(test.TestCase): def setUp(self): super(self.__class__, self).setUp() self.sg = test_data.share_group self.sg_nl = test_data.share_group_nameless self.sg_dhss_true = test_data.share_group_dhss_true self.sgs = test_data.share_group_snapshot self.sgs_nl = test_data.share_group_snapshot_nameless def test_share_group_snapshots_list_get(self): share_groups = [self.sg, self.sg_nl, self.sg_dhss_true] sgss = [self.sgs, self.sgs_nl] self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(return_value=sgss)) self.mock_object( api_manila, 'share_group_list', mock.Mock(return_value=share_groups)) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) self.assertMessageCount(error=0) self.assertNoMessages() api_manila.share_group_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) api_manila.share_group_list.assert_called_once_with(mock.ANY) self.assertTemplateUsed( res, 'project/share_group_snapshots/index.html') self.assertContains(res, "

Share Group Snapshots

") self.assertContains( res, 'Delete Share Group Snapshot', len(sgss)) self.assertContains(res, 'Delete Share Group Snapshots', 1) for sgs in sgss: self.assertContains( res, 'value="share_group_snapshots__delete__%s' % sgs.id, 1) self.assertContains( res, '%(name)s-' % self.sgs_nl.id, 1) def test_share_group_snapshots_list_error_get(self): self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) self.assertTemplateUsed( res, 'project/share_group_snapshots/index.html') self.assertContains(res, "

Share Group Snapshots

") self.assertContains(res, 'Delete Share Group Snapshot', 0) self.assertContains(res, 'Delete Share Group Snapshots', 0) self.assertNoMessages() @ddt.data( test_data.share_group_snapshot, test_data.share_group_snapshot_nameless, ) def test_share_group_snapshot_detailed_page_get(self, sgs): sg = test_data.share_group_nameless url = reverse( 'horizon:project:share_group_snapshots:detail', args=[sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=sgs)) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=sg)) res = self.client.get(url) self.assertTemplateUsed( res, 'project/share_group_snapshots/detail.html') self.assertStatusCode(res, 200) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, sgs.id) api_manila.share_group_get.assert_called_once_with( mock.ANY, sgs.share_group_id) def test_share_group_snapshot_detailed_page_error_get(self): url = reverse( 'horizon:project:share_group_snapshots:detail', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed( res, 'admin/share_group_snapshots/detail.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=1) self.assertMessageCount(success=0) @ddt.data( lambda *args, **kwargs: test_data.share_group, type('CustomExc', (Exception, ), {}), ) def test_share_group_snapshot_create_get(self, sg_get_side_effect): url = reverse( 'horizon:project:share_group_snapshots:create', args=[self.sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(side_effect=sg_get_side_effect)) res = self.client.get(url) self.assertTemplateUsed( res, 'project/share_group_snapshots/create.html') self.assertStatusCode(res, 200) self.assertNoMessages() api_manila.share_group_get.assert_called_once_with( mock.ANY, self.sg.id) self.assertMessageCount(error=0) def test_share_group_snapshot_create_post(self): url = reverse( 'horizon:project:share_group_snapshots:create', args=[self.sg.id]) form_data = { 'method': 'CreateShareGroupSnapshotForm', 'name': 'fake_SG_snapshot_name', 'description': 'fake SG snapshot description', 'share_group_id': self.sg.id, } self.mock_object( api_manila, "share_group_snapshot_create", mock.Mock(return_value=self.sgs)) res = self.client.post(url, form_data) self.assertTemplateNotUsed( res, 'project/share_group_snapshots/create.html') self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(error=0) self.assertMessageCount(success=1) api_manila.share_group_snapshot_create.assert_called_once_with( mock.ANY, self.sg.id, form_data['name'], form_data['description']) def test_share_group_snapshot_create_error_post(self): url = reverse( 'horizon:project:share_group_snapshots:create', args=[self.sg.id]) form_data = { 'method': 'CreateShareGroupSnapshotForm', 'name': 'fake_SG_snapshot_name', 'description': 'fake SG snapshot description', 'share_group_id': self.sg.id, } self.mock_object( api_manila, "share_group_snapshot_create", mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.post(url, form_data) self.assertTemplateNotUsed( res, 'project/share_group_snapshots/create.html') self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(error=1) self.assertMessageCount(success=0) api_manila.share_group_snapshot_create.assert_called_once_with( mock.ANY, self.sg.id, form_data['name'], form_data['description']) def test_share_group_snapshot_update_get(self): url = reverse( 'horizon:project:share_group_snapshots:update', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=self.sgs)) res = self.client.get(url) self.assertTemplateUsed( res, 'project/share_group_snapshots/update.html') self.assertStatusCode(res, 200) self.assertNoMessages() api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) def test_share_group_snapshot_update_error_get(self): url = reverse( 'horizon:project:share_group_snapshots:update', args=[self.sgs.id]) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed( res, 'project/share_group_snapshots/update.html') self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(error=1) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) def test_share_group_snapshot_update_post(self): self.mock_object(api_manila, "share_group_snapshot_update") self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=self.sgs)) form_data = { 'method': 'UpdateShareGroupSnapshotForm', 'name': self.sgs.name, 'description': self.sgs.description, } url = reverse( 'horizon:project:share_group_snapshots:update', args=[self.sgs.id]) res = self.client.post(url, form_data) self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_group_snapshot_update.assert_called_once_with( mock.ANY, self.sgs.id, form_data['name'], form_data['description']) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) self.assertMessageCount(error=0) self.assertMessageCount(success=1) def test_share_group_snapshot_update_error_post(self): self.mock_object( api_manila, "share_group_snapshot_update", mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) self.mock_object( api_manila, 'share_group_snapshot_get', mock.Mock(return_value=self.sgs)) form_data = { 'method': 'UpdateShareGroupSnapshotForm', 'name': self.sgs.name, 'description': self.sgs.description, } url = reverse( 'horizon:project:share_group_snapshots:update', args=[self.sgs.id]) res = self.client.post(url, form_data) self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_group_snapshot_update.assert_called_once_with( mock.ANY, self.sgs.id, form_data['name'], form_data['description']) api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, self.sgs.id) self.assertMessageCount(error=1) self.assertMessageCount(success=0) def test_share_group_snapshot_delete_post(self): data = {'action': 'share_group_snapshots__delete__%s' % self.sgs.id} self.mock_object(api_manila, "share_group_snapshot_delete") self.mock_object( api_manila, "share_group_snapshot_list", mock.Mock(return_value=[self.sgs])) res = self.client.post(INDEX_URL, data) self.assertStatusCode(res, 302) self.assertMessageCount(success=1) api_manila.share_group_snapshot_delete.assert_called_once_with( mock.ANY, self.sgs.id) api_manila.share_group_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'all_tenants': True}) self.assertRedirectsNoFollow(res, INDEX_URL) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8386514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_groups/0000775000175000017500000000000000000000000025051 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_groups/__init__.py0000664000175000017500000000000000000000000027150 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_groups/tests.py0000664000175000017500000004025100000000000026567 0ustar00zuulzuul00000000000000# Copyright (c) 2017 Mirantis, Inc. # 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 ddt from django.urls import reverse from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:share_groups:index') @ddt.ddt class ShareGroupTests(test.TestCase): def setUp(self): super(self.__class__, self).setUp() self.sg = test_data.share_group self.sg_nl = test_data.share_group_nameless self.sg_dhss_true = test_data.share_group_dhss_true def test_share_groups_list_get(self): sgs = [self.sg, self.sg_nl, self.sg_dhss_true] self.mock_object( api_manila, 'share_group_list', mock.Mock(return_value=sgs)) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) api_manila.share_group_list.assert_called_once_with( mock.ANY, detailed=True) self.assertTemplateUsed(res, 'project/share_groups/index.html') self.assertContains(res, "

Share Groups

") self.assertContains(res, 'Delete Share Group', len(sgs)) self.assertContains(res, 'Delete Share Groups', 1) for sg in sgs: self.assertContains( res, 'value="share_groups__delete__%s' % sg.id, 1) self.assertContains( res, '%(name)s' % { 'id': sg.id, 'name': sg.name}, 1) self.assertContains( res, '-' % self.sg_nl.id, 1) self.assertNoMessages() def test_share_group_list_error_get(self): self.mock_object( api_manila, 'share_group_list', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(INDEX_URL) self.assertStatusCode(res, 200) self.assertTemplateUsed(res, 'project/share_groups/index.html') self.assertContains(res, "

Share Groups

") self.assertContains(res, 'Delete Share Group', 0) self.assertContains(res, 'Delete Share Groups', 0) self.assertNoMessages() @ddt.data( test_data.share_group_nameless, test_data.share_group_dhss_true, ) def test_share_group_detailed_page_get(self, sg): url = reverse('horizon:project:share_groups:detail', args=[sg.id]) shares = [test_data.share, test_data.nameless_share] share_types = [test_data.share_type, test_data.share_type_dhss_true] capability_msg = ("Consistent snapshots are supported" if sg.consistent_snapshot_support else None) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=sg)) self.mock_object( api_manila, 'share_list', mock.Mock(return_value=shares)) self.mock_object(api_manila, 'share_group_type_get', mock.Mock(return_value=test_data.share_group_type)) self.mock_object(api_manila, 'share_type_list', mock.Mock(return_value=share_types)) res = self.client.get(url) self.assertTemplateUsed(res, 'project/share_groups/detail.html') self.assertStatusCode(res, 200) self.assertContains(res, '
Capabilities
') self.assertContains(res, capability_msg) if capability_msg else None self.assertContains(res, "Share Group Type Name:") self.assertContains(res, "Share Group Type ID:") self.assertContains(res, "Share Group Type Specs:") for share in shares: data = {'id': share.id, 'name': share.name or share.id} self.assertContains( res, '%(name)s' % data) def test_share_group_detailed_page_error_get(self): url = reverse('horizon:project:share_groups:detail', args=[self.sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed(res, 'project/share_groups/detail.html') self.assertStatusCode(res, 302) self.assertMessageCount(error=1) self.assertMessageCount(success=0) def test_share_group_update_get(self): url = reverse('horizon:project:share_groups:update', args=[self.sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=self.sg)) res = self.client.get(url) self.assertTemplateUsed(res, 'project/share_groups/update.html') self.assertStatusCode(res, 200) self.assertNoMessages() api_manila.share_group_get.assert_called_once_with( mock.ANY, self.sg.id) def test_share_group_update_error_get(self): url = reverse('horizon:project:share_groups:update', args=[self.sg.id]) self.mock_object( api_manila, 'share_group_get', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) res = self.client.get(url) self.assertTemplateNotUsed(res, 'project/share_groups/update.html') self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertMessageCount(error=1) api_manila.share_group_get.assert_called_once_with( mock.ANY, self.sg.id) def test_share_group_update_post(self): self.mock_object(api_manila, "share_group_update") self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=self.sg)) form_data = { 'method': 'UpdateShareGroupForm', 'name': self.sg.name, 'description': self.sg.description, } url = reverse('horizon:project:share_groups:update', args=[self.sg.id]) res = self.client.post(url, form_data) self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_group_update.assert_called_once_with( mock.ANY, self.sg.id, form_data['name'], form_data['description']) api_manila.share_group_get.assert_called_once_with( mock.ANY, self.sg.id) self.assertMessageCount(error=0) self.assertMessageCount(success=1) def test_share_group_update_error_post(self): self.mock_object( api_manila, 'share_group_update', mock.Mock(side_effect=type('CustomExc', (Exception, ), {}))) self.mock_object( api_manila, 'share_group_get', mock.Mock(return_value=self.sg)) form_data = { 'method': 'UpdateShareGroupForm', 'name': self.sg.name, 'description': self.sg.description, } url = reverse('horizon:project:share_groups:update', args=[self.sg.id]) res = self.client.post(url, form_data) self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_group_update.assert_called_once_with( mock.ANY, self.sg.id, form_data['name'], form_data['description']) api_manila.share_group_get.assert_called_once_with( mock.ANY, self.sg.id) self.assertMessageCount(error=1) self.assertMessageCount(success=0) def test_share_group_delete_post(self): sg = test_data.share_group_dhss_true data = {'action': 'share_groups__delete__%s' % sg.id} self.mock_object(api_manila, "share_group_delete") self.mock_object( api_manila, "share_group_list", mock.Mock(return_value=[sg])) res = self.client.post(INDEX_URL, data) self.assertStatusCode(res, 302) self.assertMessageCount(success=1) api_manila.share_group_delete.assert_called_once_with(mock.ANY, sg.id) api_manila.share_group_list.assert_called_once_with( mock.ANY, detailed=True) self.assertRedirectsNoFollow(res, INDEX_URL) def test_share_group_create_get(self): url = reverse('horizon:project:share_groups:create') self.mock_object( api_manila, 'share_group_type_list', mock.Mock(return_value=[ test_data.share_group_type, test_data.share_group_type_private, test_data.share_group_type_dhss_true, ])) self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(return_value=[ test_data.share_group_snapshot, test_data.share_group_snapshot_nameless, ])) self.mock_object( api_manila, 'share_network_list', mock.Mock(return_value=[ test_data.inactive_share_network, test_data.active_share_network, ])) self.mock_object( api_manila, 'share_type_list', mock.Mock(return_value=[ test_data.share_type, test_data.share_type_private, test_data.share_type_dhss_true, ])) self.mock_object( api_manila, 'availability_zone_list', mock.Mock(return_value=[])) res = self.client.get(url) self.assertTemplateUsed(res, 'project/share_groups/create.html') self.assertStatusCode(res, 200) self.assertNoMessages() self.assertMessageCount(error=0) api_manila.share_group_type_list.assert_called_once_with(mock.ANY) api_manila.share_group_snapshot_list.assert_called_once_with(mock.ANY) api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_type_list.assert_called_once_with(mock.ANY) api_manila.availability_zone_list.assert_called_once_with(mock.ANY) def test_share_group_create_post(self): url = reverse('horizon:project:share_groups:create') form_data = { 'method': 'CreateShareGroupForm', 'name': 'fake_sg_name', 'description': 'fake SG description', 'sgt': utils.transform_dashed_name(test_data.share_group_type.id), 'share-type-choices-%s' % utils.transform_dashed_name( test_data.share_group_type.id): ( test_data.share_group_type.share_types[0] ), 'availability_zone': '', 'share_network': test_data.inactive_share_network.id, 'snapshot': '', } self.mock_object( api_manila, "share_group_create", mock.Mock(return_value=self.sg)) self.mock_object( api_manila, 'share_group_type_list', mock.Mock(return_value=[ test_data.share_group_type, test_data.share_group_type_private, test_data.share_group_type_dhss_true, ])) self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(return_value=[ test_data.share_group_snapshot, test_data.share_group_snapshot_nameless, ])) self.mock_object( api_manila, 'share_network_list', mock.Mock(return_value=[ test_data.inactive_share_network, test_data.active_share_network, ])) self.mock_object( api_manila, 'share_type_list', mock.Mock(return_value=[ test_data.share_type, test_data.share_type_private, test_data.share_type_dhss_true, ])) self.mock_object( api_manila, 'availability_zone_list', mock.Mock(return_value=[])) res = self.client.post(url, form_data) self.assertTemplateNotUsed(res, 'project/share_groups/create.html') self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_group_type_list.assert_called_once_with(mock.ANY) api_manila.share_group_snapshot_list.assert_called_once_with(mock.ANY) api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_type_list.assert_called_once_with(mock.ANY) api_manila.availability_zone_list.assert_called_once_with(mock.ANY) api_manila.share_group_create.assert_called_once_with( mock.ANY, name=form_data['name'], description=form_data['description'], share_group_type=test_data.share_group_type.id, share_types=[test_data.share_type.id], share_network=form_data['share_network'], source_share_group_snapshot=None, availability_zone=form_data['availability_zone']) def test_share_group_create_from_snapshot_post(self): url = reverse('horizon:project:share_groups:create') form_data = { 'method': 'CreateShareGroupForm', 'name': 'fake_sg_name', 'description': 'fake SG description', 'sgt': '', 'snapshot': test_data.share_group_snapshot.id, } self.mock_object( api_manila, "share_group_snapshot_get", mock.Mock(return_value=test_data.share_group_snapshot)) self.mock_object( api_manila, "share_group_get", mock.Mock(return_value=self.sg_nl)) self.mock_object( api_manila, "share_group_create", mock.Mock(return_value=self.sg)) self.mock_object( api_manila, 'share_group_type_list', mock.Mock(return_value=[ test_data.share_group_type, test_data.share_group_type_private, test_data.share_group_type_dhss_true, ])) self.mock_object( api_manila, 'share_group_snapshot_list', mock.Mock(return_value=[ test_data.share_group_snapshot, test_data.share_group_snapshot_nameless, ])) self.mock_object( api_manila, 'share_network_list', mock.Mock(return_value=[ test_data.inactive_share_network, test_data.active_share_network, ])) self.mock_object( api_manila, 'share_type_list', mock.Mock(return_value=[ test_data.share_type, test_data.share_type_private, test_data.share_type_dhss_true, ])) self.mock_object( api_manila, 'availability_zone_list', mock.Mock(return_value=[])) res = self.client.post(url, form_data) self.assertTemplateNotUsed(res, 'project/share_groups/create.html') self.assertStatusCode(res, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_group_snapshot_list.assert_not_called() api_manila.share_group_type_list.assert_not_called() api_manila.share_network_list.assert_not_called() api_manila.share_type_list.assert_not_called() api_manila.availability_zone_list.assert_not_called() api_manila.share_group_snapshot_get.assert_called_once_with( mock.ANY, test_data.share_group_snapshot.id) api_manila.share_group_create.assert_called_once_with( mock.ANY, name=form_data['name'], description=form_data['description'], share_group_type=test_data.share_group_type.id, share_types=None, share_network=None, source_share_group_snapshot=test_data.share_group_snapshot.id, availability_zone=None) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_networks/0000775000175000017500000000000000000000000025406 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_networks/__init__.py0000664000175000017500000000000000000000000027505 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_networks/tests.py0000664000175000017500000002671100000000000027131 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from neutronclient.client import exceptions from openstack_auth import policy from openstack_dashboard import api from oslo_utils import timeutils from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:share_networks:index') class ShareNetworksViewTests(test.TestCase): class FakeAZ(object): def __init__(self, name, id): self.name = name self.id = id self.created_at = timeutils.utcnow() def test_create_share_network(self): share_net = test_data.active_share_network url = reverse('horizon:project:share_networks:share_network_create') neutron_net_id = self.networks.first().id sanitized_net_id = utils.transform_dashed_name(neutron_net_id) formData = { 'share_network_name': 'new_share_network', 'share_network_description': 'This is test share network', 'method': 'CreateForm', 'neutron_net_id': utils.transform_dashed_name(neutron_net_id), 'availability_zone': 'fake_az', f'subnet-choices-{sanitized_net_id}': self.networks.first().subnets[0].id, } self.mock_object( api.neutron, "subnet_list", mock.Mock(return_value=self.subnets.list())) self.mock_object( api.neutron, "network_list", mock.Mock(return_value=self.networks.list())) self.mock_object( api_manila, "share_network_create", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[self.FakeAZ('fake_az', 'fake_az')]) ) res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertMessageCount(error=0, warning=0) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_network_create.assert_called_once_with( mock.ANY, name=formData['share_network_name'], neutron_net_id=neutron_net_id, neutron_subnet_id=self.networks.first().subnets[0].id, description=formData['share_network_description'], availability_zone='fake_az') api_manila.availability_zone_list.assert_called_once_with(mock.ANY) api.neutron.network_list.assert_called_once_with(mock.ANY) api.neutron.subnet_list.assert_has_calls([ mock.call(mock.ANY, network_id=network.id) for network in self.networks.list() ], any_order=True) def test_delete_share_network(self): share_network = test_data.inactive_share_network formData = {'action': 'share_networks__delete__%s' % share_network.id} self.mock_object(api_manila, "share_network_delete") self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=[ test_data.active_share_network, share_network])) res = self.client.post(INDEX_URL, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_network_list.assert_called_once_with( mock.ANY, detailed=True) api_manila.share_network_delete.assert_called_once_with( mock.ANY, share_network.id) def test_detail_view(self): share_net = test_data.active_share_network sec_service = test_data.sec_service share_network_subnets = share_net.share_network_subnets self.mock_object( api_manila, "share_server_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_get", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "share_network_security_service_list", mock.Mock(return_value=[sec_service])) network = self.networks.first() subnet = self.subnets.first() self.mock_object( api.neutron, "network_get", mock.Mock(return_value=network)) self.mock_object( api.neutron, "subnet_get", mock.Mock(return_value=subnet)) self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[self.FakeAZ('fake_az', 'fake_az')]) ) url = reverse('horizon:project:share_networks:share_network_detail', args=[share_net.id]) res = self.client.get(url) self.assertNoMessages() self.assertContains(res, "

Share Network Details: %s

" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.id, 1, 200) for sub in share_network_subnets: self.assertContains(res, "%s" % ( sub['neutron_net_id'], network.name), 1, 200) self.assertContains(res, "%s" % ( sub['neutron_subnet_id'], subnet['name']), 1, 200) network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id']) for sub in share_network_subnets] subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id']) for sub in share_network_subnets] api.neutron.network_get.assert_has_calls(network_get_calls, any_order=True) api.neutron.subnet_get.assert_has_calls(subnet_get_calls, any_order=True) self.assertContains(res, "%s" % (sec_service.id, sec_service.name), 1, 200) api_manila.share_network_security_service_list.assert_called_once_with( mock.ANY, share_net.id) api_manila.share_server_list.assert_called_once_with( mock.ANY, search_opts={'share_network_id': share_net.id}) api_manila.share_network_get.assert_called_once_with( mock.ANY, share_net.id) def test_detail_view_network_not_found(self): share_net = test_data.active_share_network sec_service = test_data.sec_service share_network_subnets = share_net.share_network_subnets url = reverse('horizon:project:share_networks:share_network_detail', args=[share_net.id]) self.mock_object( api_manila, "share_server_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_get", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "share_network_security_service_list", mock.Mock(return_value=[sec_service])) self.mock_object( api.neutron, "network_get", mock.Mock( side_effect=exceptions.NeutronClientException('fake', 500))) self.mock_object( api.neutron, "subnet_get", mock.Mock( side_effect=exceptions.NeutronClientException('fake', 500))) self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[]) ) res = self.client.get(url) self.assertContains(res, "

Share Network Details: %s

" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.name, 1, 200) self.assertContains(res, "
%s
" % share_net.id, 1, 200) for sub in share_network_subnets: self.assertNotContains(res, "
%s
" % sub['neutron_net_id']) self.assertNotContains(res, "
%s
" % sub['neutron_subnet_id']) network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id'] ) for sub in share_network_subnets] subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id'] ) for sub in share_network_subnets] api.neutron.network_get.assert_has_calls(network_get_calls, any_order=True) api.neutron.subnet_get.assert_has_calls(subnet_get_calls, any_order=True) self.assertContains(res, "%s" % (sec_service.id, sec_service.name), 1, 200) self.assertNoMessages() api_manila.share_network_security_service_list.assert_called_once_with( mock.ANY, share_net.id) api_manila.share_server_list.assert_called_once_with( mock.ANY, search_opts={'share_network_id': share_net.id}) api_manila.share_network_get.assert_called_once_with( mock.ANY, share_net.id) def test_update_share_network(self): share_net = test_data.inactive_share_network formData = { 'method': 'UpdateForm', 'name': share_net.name, 'description': share_net.description, } url = reverse('horizon:project:share_networks:share_network_update', args=[share_net.id]) self.mock_object(api_manila, "share_network_update") self.mock_object( api_manila, "share_network_get", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "share_network_security_service_list", mock.Mock(return_value=[test_data.sec_service])) self.mock_object( api_manila, "security_service_list", mock.Mock(return_value=[test_data.sec_service])) self.mock_object( policy, 'check', mock.Mock(side_effect=(lambda *args, **kwargs: True))) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_network_security_service_list.assert_called_once_with( mock.ANY, share_net.id) api_manila.security_service_list.assert_has_calls([ mock.call(mock.ANY), mock.call(mock.ANY, search_opts={'share_network_id': share_net.id}) ]) api_manila.share_network_get.assert_called_once_with( mock.ANY, share_net.id) api_manila.share_network_update.assert_called_once_with( mock.ANY, share_net.id, name=formData['name'], description=formData['description']) self.assertTrue(policy.check.called) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_snapshots/0000775000175000017500000000000000000000000025554 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_snapshots/__init__.py0000664000175000017500000000000000000000000027653 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_snapshots/test_tables.py0000664000175000017500000000526300000000000030445 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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. from io import BytesIO import ddt from django.core.handlers import wsgi from django.core.handlers.wsgi import LimitedStream from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.project.share_snapshots import tables from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as base @ddt.ddt class CreateSnapshotTests(base.APITestCase): def setUp(self): super(self.__class__, self).setUp() stream = LimitedStream(BytesIO(b"test"), 2) FAKE_ENVIRON = {'REQUEST_METHOD': 'GET', 'wsgi.input': stream} self.request = wsgi.WSGIRequest(FAKE_ENVIRON) self.create_snapshot = tables.CreateShareSnapshot() def _get_fake_share(self, **kwargs): if 'status' not in kwargs.keys(): kwargs.update({'status': 'available'}) return type("Share", (object, ), kwargs)() @ddt.data(True, False) def test_allowed_with_snapshot_support_attr(self, snapshot_support): self.mock_object( api_manila, "tenant_absolute_limits", mock.Mock(return_value=test_data.limits)) share = self._get_fake_share(snapshot_support=snapshot_support) result = self.create_snapshot.allowed(self.request, share) self.assertEqual(snapshot_support, result) def test_allowed_no_snapshot_support_attr(self): self.mock_object( api_manila, "tenant_absolute_limits", mock.Mock(return_value=test_data.limits)) share = self._get_fake_share() result = self.create_snapshot.allowed(self.request, share) self.assertNotIn('disabled', self.create_snapshot.classes) self.assertTrue(result) def test_allowed_no_snapshot_support_attr_no_quota(self): self.mock_object( api_manila, "tenant_absolute_limits", mock.Mock(return_value=test_data.limits_negative)) share = self._get_fake_share() result = self.create_snapshot.allowed(self.request, share) self.assertIn('disabled', self.create_snapshot.classes) self.assertTrue(result) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/share_snapshots/tests.py0000664000175000017500000003153200000000000027274 0ustar00zuulzuul00000000000000# Copyright 2014 NetApp, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ddt from django.urls import reverse from openstack_dashboard.api import neutron from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:share_snapshots:index') @ddt.ddt class SnapshotSnapshotViewTests(test.TestCase): def test_create_snapshot_get(self): share = test_data.share usage_limit = { 'maxTotalShareGigabytes': 250, 'totalShareGigabytesUsed': 20, } url = reverse('horizon:project:share_snapshots:share_snapshot_create', args=[share.id]) self.mock_object( api_manila, "tenant_absolute_limits", mock.Mock(return_value=usage_limit)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) self.assertNoMessages() self.assertTemplateUsed(res, 'project/share_snapshots/create.html') def test_create_snapshot_post(self): share = test_data.share snapshot = test_data.snapshot url = reverse('horizon:project:share_snapshots:share_snapshot_create', args=[share.id]) formData = { 'name': 'new_snapshot', 'description': 'This is test snapshot', 'method': 'CreateForm', 'size': 1, 'type': 'NFS', 'share_id': share.id, } self.mock_object( api_manila, "share_snapshot_create", mock.Mock(return_value=snapshot)) res = self.client.post(url, formData) api_manila.share_snapshot_create.assert_called_once_with( mock.ANY, share.id, formData['name'], formData['description']) self.assertRedirectsNoFollow(res, INDEX_URL) def test_delete_snapshot(self): share = test_data.share snapshot = test_data.snapshot formData = {'action': 'share_snapshots__delete__%s' % snapshot.id} self.mock_object(api_manila, "share_snapshot_delete") self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[snapshot])) self.mock_object( api_manila, "share_list", mock.Mock(return_value=[share])) res = self.client.post(INDEX_URL, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_snapshot_list.assert_called_once_with(mock.ANY) api_manila.share_list.assert_called_once_with(mock.ANY) api_manila.share_snapshot_delete.assert_called_once_with( mock.ANY, test_data.snapshot.id) def test_detail_view(self): snapshot = test_data.snapshot share = test_data.share url = reverse('horizon:project:share_snapshots:share_snapshot_detail', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) res = self.client.get(url) self.assertContains(res, "

Snapshot Details: %s

" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.id, 1, 200) self.assertContains(res, "
%s
" % (snapshot.share_id, share.name), 1, 200) self.assertContains(res, "
%s GiB
" % snapshot.size, 1, 200) self.assertNoMessages() api_manila.share_get.assert_called_once_with(mock.ANY, share.id) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) def test_detail_view_with_mount_support(self): snapshot = test_data.snapshot_mount_support share = test_data.share_mount_snapshot rules = [test_data.ip_rule, test_data.user_rule, test_data.cephx_rule] export_locations = test_data.user_snapshot_export_locations url = reverse('horizon:project:share_snapshots:share_snapshot_detail', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) self.mock_object( api_manila, "share_snapshot_rules_list", mock.Mock( return_value=rules)) self.mock_object( api_manila, "share_snap_export_location_list", mock.Mock( return_value=export_locations)) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) res = self.client.get(url) self.assertContains(res, "

Snapshot Details: %s

" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.name, 1, 200) self.assertContains(res, "
%s
" % snapshot.id, 1, 200) self.assertContains(res, "
%s
" % (snapshot.share_id, share.name), 1, 200) self.assertContains(res, "
%s GiB
" % snapshot.size, 1, 200) for el in export_locations: self.assertContains(res, "value=\"%s\"" % el.path, 1, 200) for rule in rules: self.assertContains(res, "
%s
" % rule.access_type, 1, 200) self.assertContains( res, "
Access to: %s
" % rule.access_to, 1, 200) self.assertContains( res, "
Status: active
", len(rules), 200) self.assertNoMessages() api_manila.share_get.assert_called_once_with(mock.ANY, share.id) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) api_manila.share_snapshot_rules_list.assert_called_once_with( mock.ANY, snapshot.id) api_manila.share_snap_export_location_list.assert_called_once_with( mock.ANY, snapshot) def test_update_snapshot_get(self): snapshot = test_data.snapshot url = reverse('horizon:project:share_snapshots:share_snapshot_edit', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) self.assertNoMessages() self.assertTemplateUsed(res, 'project/share_snapshots/update.html') def test_update_snapshot_post(self): snapshot = test_data.snapshot url = reverse('horizon:project:share_snapshots:share_snapshot_edit', args=[snapshot.id]) formData = { 'method': 'UpdateForm', 'name': snapshot.name, 'description': snapshot.description, } self.mock_object(api_manila, "share_snapshot_update") self.mock_object(api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) api_manila.share_snapshot_update.assert_called_once_with( mock.ANY, snapshot.id, formData['name'], formData['description']) def test_list_rules(self): snapshot = test_data.snapshot rules = [test_data.ip_rule, test_data.user_rule, test_data.cephx_rule] self.mock_object( api_manila, "share_snapshot_get", mock.Mock( return_value=snapshot)) self.mock_object( api_manila, "share_snapshot_rules_list", mock.Mock( return_value=rules)) url = reverse( 'horizon:project:share_snapshots:share_snapshot_manage_rules', args=[snapshot.id]) res = self.client.get(url) self.assertEqual(res.status_code, 200) self.assertTemplateUsed( res, 'project/share_snapshots/manage_rules.html') api_manila.share_snapshot_rules_list.assert_called_once_with( mock.ANY, snapshot.id) def test_list_rules_exception(self): snapshot = test_data.snapshot self.mock_object( api_manila, "share_snapshot_get", mock.Mock( return_value=snapshot)) self.mock_object( api_manila, "share_snapshot_rules_list", mock.Mock(side_effect=Exception('fake'))) url = reverse( 'horizon:project:share_snapshots:share_snapshot_manage_rules', args=[snapshot.id]) res = self.client.get(url) self.assertEqual(res.status_code, 302) self.assertTemplateNotUsed( res, 'project/share_snapshots/manage_rules.html') api_manila.share_snapshot_rules_list.assert_called_once_with( mock.ANY, snapshot.id) def test_create_rule_get(self): snapshot = test_data.snapshot url = reverse( 'horizon:project:share_snapshots:share_snapshot_rule_add', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock( return_value=snapshot)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) self.assertNoMessages() self.assertTemplateUsed(res, 'project/share_snapshots/rule_add.html') def test_create_rule_get_exception(self): snapshot = test_data.snapshot url = reverse( 'horizon:project:share_snapshots:share_snapshot_rule_add', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_get", mock.Mock( side_effect=Exception('fake'))) res = self.client.get(url) self.assertEqual(res.status_code, 302) self.assertTemplateNotUsed( res, 'project/share_snapshots/rule_add.html') @ddt.data(None, Exception('fake')) def test_create_rule_post(self, exc): snapshot = test_data.snapshot self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) url = reverse( 'horizon:project:share_snapshots:share_snapshot_rule_add', args=[snapshot.id]) self.mock_object( api_manila, "share_snapshot_allow", mock.Mock(side_effect=exc)) formData = { 'access_type': 'user', 'method': 'CreateForm', 'access_to': 'someuser', } res = self.client.post(url, formData) self.assertEqual(res.status_code, 302) api_manila.share_snapshot_allow.assert_called_once_with( mock.ANY, snapshot.id, access_type=formData['access_type'], access_to=formData['access_to']) self.assertRedirectsNoFollow( res, reverse( 'horizon:project:share_snapshots:share_snapshot_manage_rules', args=[snapshot.id]) ) @ddt.data(None, Exception('fake')) def test_delete_rule(self, exc): snapshot = test_data.snapshot rule = test_data.ip_rule formData = {'action': 'rules__delete__%s' % rule.id} self.mock_object( api_manila, "share_snapshot_get", mock.Mock( return_value=snapshot)) self.mock_object(api_manila, "share_snapshot_deny", mock.Mock(side_effect=exc)) self.mock_object( api_manila, "share_snapshot_rules_list", mock.Mock( return_value=[rule])) url = reverse( 'horizon:project:share_snapshots:share_snapshot_manage_rules', args=[snapshot.id]) res = self.client.post(url, formData) self.assertEqual(res.status_code, 302) api_manila.share_snapshot_deny.assert_called_with( mock.ANY, snapshot.id, rule.id) api_manila.share_snapshot_rules_list.assert_called_with( mock.ANY, snapshot.id) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/shares/0000775000175000017500000000000000000000000023635 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/shares/__init__.py0000664000175000017500000000000000000000000025734 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/shares/replicas/0000775000175000017500000000000000000000000025437 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/shares/replicas/__init__.py0000664000175000017500000000000000000000000027536 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/shares/replicas/tests.py0000664000175000017500000003167200000000000027164 0ustar00zuulzuul00000000000000# Copyright (c) 2016 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ddt from django.urls import reverse from openstack_dashboard.api import neutron from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.project.shares.replicas import tables as r_tables from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:shares:index') class FakeAZ(object): def __init__(self, name): self.name = name @ddt.ddt class ReplicasTests(test.TestCase): def setUp(self): super(self.__class__, self).setUp() self.share = test_data.share self.share_replica = test_data.share_replica self.share_replica2 = test_data.share_replica2 self.mock_object( api_manila, "share_get", mock.Mock(return_value=self.share)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) def test_create_get(self): url = reverse( "horizon:project:shares:create_replica", args=[self.share.id]) old_az = self.share.availability_zone new_az = old_az + "_new" self.mock_object(api_manila, "share_replica_create") self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[FakeAZ(new_az), FakeAZ(old_az)])) res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertFalse(api_manila.share_replica_create.called) api_manila.availability_zone_list.assert_called_once_with(mock.ANY) self.assertNoMessages() self.assertTemplateUsed( res, "project/shares/replicas/create_replica.html") def _create_post(self): url = reverse( "horizon:project:shares:create_replica", args=[self.share.id]) old_az = self.share.availability_zone new_az = old_az + "_new" formData = { "share_id": self.share.id, "availability_zone": new_az, } self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[FakeAZ(new_az), FakeAZ(old_az)])) self.mock_object( api_manila, "share_replica_create", mock.Mock(return_value=test_data.share_replica)) res = self.client.post(url, formData) self.assertEqual(302, res.status_code) api_manila.share_replica_create.assert_called_once_with( mock.ANY, self.share.id, formData["availability_zone"]) api_manila.share_replica_create.assert_called_once_with( mock.ANY, formData["share_id"], formData["availability_zone"]) api_manila.availability_zone_list.assert_called_once_with(mock.ANY) self.assertRedirectsNoFollow( res, reverse("horizon:project:shares:manage_replicas", args=[self.share.id])) def test_create_post(self): self.mock_object(api_manila, "share_replica_create") self._create_post() def test_create_post_error(self): self.mock_object( api_manila, "share_replica_create", mock.Mock(side_effect=Exception("Fake exception"))) self._create_post() @ddt.data(True, False) def test_detail_with_export_locations_available(self, exports_available): url = reverse( "horizon:project:shares:replica_detail", args=[self.share_replica.id]) export_locations_call_behavior = ( {'return_value': test_data.export_locations} if exports_available else {'side_effect': Exception("Access denied to this resource")} ) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) self.mock_object( api_manila, "share_instance_export_location_list", mock.Mock(**export_locations_call_behavior)) res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed(res, "project/shares/replicas/detail.html") self.assertNoMessages() self.assertContains(res, "

Share Replica Overview", 1, 200) self.assertContains(res, ">%s" % self.share.id, 1, 200) self.assertContains(res, "
%s
" % self.share_replica.id, 1, 200) self.assertContains( res, "
%s
" % self.share.availability_zone, 1, 200) if exports_available: for el in test_data.export_locations: self.assertContains(res, "value=\"%s\"" % el.path, 1, 200) self.assertContains( res, "
Preferred: %s
" % el.preferred, 1, 200) self.assertContains( res, "
Is admin only: %s
" % el.is_admin_only, 1, 200) self.assertNoMessages() api_manila.share_replica_get.assert_called_once_with( mock.ANY, self.share_replica.id) api_manila.share_instance_export_location_list.assert_called_once_with( mock.ANY, self.share_replica.id) def test_detail_not_found(self): url = reverse("horizon:project:shares:replica_detail", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock( side_effect=Exception("Fake replica NotFound exception"))) self.mock_object(api_manila, "share_instance_export_location_list") res = self.client.get(url) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertTemplateNotUsed(res, "project/shares/replicas/detail.html") api_manila.share_replica_get.assert_called_once_with( mock.ANY, self.share_replica.id) self.assertFalse(api_manila.share_instance_export_location_list.called) def test_list(self): self.mock_object( api_manila, "share_replica_list", mock.Mock(return_value=[self.share_replica])) url = reverse( "horizon:project:shares:manage_replicas", args=[self.share.id]) res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed( res, "project/shares/replicas/manage_replicas.html") api_manila.share_get.assert_called_with(mock.ANY, self.share.id) api_manila.share_replica_list.assert_called_with( mock.ANY, self.share.id) def test_list_exception(self): self.mock_object( api_manila, "share_replica_list", mock.Mock(side_effect=Exception("Fake exception"))) url = reverse( "horizon:project:shares:manage_replicas", args=[self.share.id]) res = self.client.get(url) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, INDEX_URL) self.assertTemplateNotUsed( res, "project/shares/replicas/manage_replicas.html") api_manila.share_replica_list.assert_called_with( mock.ANY, self.share.id) @ddt.data( ([test_data.share_replica], test_data.share_replica.id, None), ([test_data.share_replica], test_data.share_replica.id, 'dr'), ([test_data.share_replica], test_data.share_replica.id, 'readable'), ([test_data.share_replica], test_data.share_replica.id, 'writable'), ([test_data.share_replica, test_data.share_replica2], test_data.share_replica.id, 'dr'), ([test_data.share_replica, test_data.share_replica2], test_data.share_replica.id, 'readable'), ) @ddt.unpack def test_delete_not_allowed(self, replica_list, replica_id, replication_type): share = test_data.share share.replication_type = replication_type formData = {"action": "replicas__delete__%s" % replica_id} self.mock_object(api_manila, "share_replica_delete") self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_replica_list", mock.Mock(return_value=replica_list)) url = reverse( "horizon:project:shares:manage_replicas", args=[share.id]) res = self.client.post(url, formData) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, url) api_manila.share_replica_list.assert_called_with(mock.ANY, share.id) self.assertFalse(api_manila.share_replica_delete.called) @ddt.data( ([test_data.share_replica, test_data.share_replica2], test_data.share_replica2.id, 'dr'), ([test_data.share_replica, test_data.share_replica2], test_data.share_replica2.id, 'readable'), ([test_data.share_replica, test_data.share_replica3], test_data.share_replica.id, 'writable'), ([test_data.share_replica, test_data.share_replica3], test_data.share_replica3.id, 'writable'), ) @ddt.unpack def test_delete_allowed(self, replica_list, replica_id, replication_type): share = test_data.share share.replication_type = replication_type formData = {"action": "replicas__delete__%s" % replica_id} self.mock_object(api_manila, "share_replica_delete") self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_replica_list", mock.Mock(return_value=replica_list)) url = reverse( "horizon:project:shares:manage_replicas", args=[share.id]) res = self.client.post(url, formData) self.assertEqual(302, res.status_code) self.assertRedirectsNoFollow(res, url) api_manila.share_replica_list.assert_called_with(mock.ANY, share.id) api_manila.share_replica_delete.assert_called_with( mock.ANY, replica_id) def test_set_as_active_get(self): url = reverse( "horizon:project:shares:set_replica_as_active", args=[self.share_replica.id]) self.mock_object(api_manila, "share_replica_get") self.mock_object(api_manila, "share_replica_promote") res = self.client.get(url) self.assertEqual(200, res.status_code) self.assertTemplateUsed( res, "project/shares/replicas/set_replica_as_active.html") self.assertFalse(api_manila.share_replica_get.called) self.assertFalse(api_manila.share_replica_promote.called) def _set_as_active_post(self): url = reverse( "horizon:project:shares:set_replica_as_active", args=[self.share_replica.id]) self.mock_object( api_manila, "share_replica_get", mock.Mock(return_value=self.share_replica)) formData = {"replica_id": self.share_replica.id} res = self.client.post(url, formData) self.assertEqual(302, res.status_code) self.assertTemplateNotUsed( res, "project/shares/replicas/set_replica_as_active.html") api_manila.share_replica_promote.assert_called_once_with( mock.ANY, self.share_replica) return res def test_set_as_active_post(self): self.mock_object(api_manila, "share_replica_promote") res = self._set_as_active_post() self.assertRedirectsNoFollow( res, reverse("horizon:project:shares:manage_replicas", args=[self.share.id])) def test_set_as_active_post_error(self): self.mock_object( api_manila, "share_replica_promote", mock.Mock(side_effect=Exception("Fake exception"))) res = self._set_as_active_post() self.assertRedirectsNoFollow( res, reverse("horizon:project:shares:index")) def test_replicas_table(self): replicas_table = r_tables.ReplicasTable(self.request) counter = 0 columns = ['created_at', 'updated_at'] for column in replicas_table.get_columns(): if column.name in columns: self.assertEqual(1, len(column.filters)) self.assertEqual( column.filters[0], r_tables.filters.parse_isotime) counter += 1 columns.remove(column.name) self.assertEqual( 2, counter, "The following columns are missing: %s." % ', '.join(columns)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/shares/tests.py0000664000175000017500000007735400000000000025371 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from io import BytesIO import ddt from django.core.handlers import wsgi from django.core.handlers.wsgi import LimitedStream from django.urls import reverse from horizon import messages as horizon_messages from openstack_dashboard.api import neutron from unittest import mock from manila_ui.api import manila as api_manila from manila_ui.dashboards.project.shares import forms from manila_ui.dashboards import utils from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:shares:index') @ddt.ddt class ShareViewTests(test.APITestCase): class FakeAZ(object): def __init__(self, name): self.name = name def setUp(self): super(ShareViewTests, self).setUp() self.fake_share_type = mock.Mock() self.fake_share_type.name = 'fake' self.fake_share_type.id = 'fake_id' self.fake_share_type.get_keys = mock.Mock( return_value={'driver_handles_share_servers': 'True'}) self.share = test_data.share self.mock_object( api_manila, "share_group_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_get", mock.Mock(return_value=self.share)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) self.mock_object(horizon_messages, "success") stream = LimitedStream(BytesIO(b"test"), 2) FAKE_ENVIRON = {'REQUEST_METHOD': 'GET', 'wsgi.input': stream} self.request = wsgi.WSGIRequest(FAKE_ENVIRON) self.mock_object( api_manila, "tenant_absolute_limits", mock.Mock(return_value=test_data.limits)) def test_index(self): snaps = [test_data.snapshot, test_data.snapshot_mount_support] shares = [test_data.share, test_data.nameless_share, test_data.other_share] share_networks = [test_data.inactive_share_network, test_data.active_share_network] self.mock_object( api_manila, "share_list", mock.Mock(return_value=shares)) self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=snaps)) self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=share_networks)) self.mock_object( api_manila, "tenant_absolute_limits", mock.Mock(return_value=test_data.limits)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(INDEX_URL) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, 'project/shares/index.html') api_manila.share_snapshot_list.assert_called_with( mock.ANY, detailed=True) api_manila.share_list.assert_called_with(mock.ANY) api_manila.share_network_list.assert_called_with(mock.ANY) api_manila.tenant_absolute_limits.assert_called_with(mock.ANY) @mock.patch.object(api_manila, 'availability_zone_list') def test_create_share(self, az_list): url = reverse('horizon:project:shares:create') share = test_data.share share_net = test_data.active_share_network share_nets = [share_net] fake_share_type = mock.Mock() fake_share_type.name = 'fake-type' fake_share_type.id = '5f3f4705-153d-4864-9930-a01c6bbea0bb' fake_share_type.get_keys = mock.Mock(return_value={ 'driver_handles_share_servers': 'True'}) formData = { 'name': 'new_share', 'description': 'This is test share', 'method': 'CreateForm', 'share_network': share_net.id, 'size': 1, 'share_proto': 'NFS', 'share_type': utils.transform_dashed_name('fake-type'), 'share-network-choices-%s' % utils.transform_dashed_name( 'fake-type'): share_net.id, 'availability_zone': 'fake_az', } az_list.return_value = [self.FakeAZ('fake_az'), ] self.mock_object( api_manila, "share_create", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=share_nets)) self.mock_object( api_manila, "share_type_list", mock.Mock(return_value=[fake_share_type, ])) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_create.assert_called_once_with( mock.ANY, size=formData['size'], name=formData['name'], description=formData['description'], proto=formData['share_proto'], snapshot_id=None, is_public=False, share_group_id=None, share_network=share_net.id, metadata={}, share_type='fake-type', availability_zone=formData['availability_zone']) api_manila.share_snapshot_list.assert_called_once_with(mock.ANY) api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_type_list.assert_called_once_with(mock.ANY) @mock.patch.object(api_manila, 'availability_zone_list') def test_create_share_from_snapshot(self, mock_az_list): share = test_data.share share_net = test_data.active_share_network share_nets = [share_net] snapshot = test_data.snapshot url = reverse('horizon:project:shares:create') formData = { 'name': 'new_share', 'description': 'This is test share from snapshot', 'method': 'CreateForm', 'share_network': share_net.id, 'size': snapshot.size, 'share_proto': 'NFS', 'share_type': 'fake', 'share_source_type': 'snapshot', 'snapshot': snapshot.id, 'share-network-choices-fake': share_net.id, } self.mock_object( api_manila, "share_create", mock.Mock(return_value=share)) self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[snapshot])) self.mock_object( api_manila, "share_snapshot_get", mock.Mock(return_value=snapshot)) self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=share_nets)) self.mock_object( api_manila, "share_type_list", mock.Mock(return_value=[self.fake_share_type, ])) res = self.client.post(url, formData) api_manila.share_snapshot_list.assert_not_called() api_manila.share_snapshot_get.assert_called_once_with( mock.ANY, snapshot.id) api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_type_list.assert_called_once_with(mock.ANY) api_manila.share_create.assert_called_with( mock.ANY, size=formData['size'], name=formData['name'], description=formData['description'], proto=formData['share_proto'], snapshot_id=snapshot.id, is_public=False, share_group_id=None, share_network=share_net.id, metadata={}, share_type=formData['share_type'], availability_zone=None) self.assertRedirectsNoFollow(res, INDEX_URL) def test_delete_share(self): formData = {'action': 'shares__delete__%s' % self.share.id} self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=[])) self.mock_object(api_manila, "share_delete") self.mock_object( api_manila, "share_get", mock.Mock(return_value=self.share)) self.mock_object( api_manila, "share_list", mock.Mock(return_value=[self.share])) res = self.client.post(INDEX_URL, formData) api_manila.share_network_list.assert_called_once_with(mock.ANY) api_manila.share_snapshot_list.assert_called_once_with( mock.ANY, detailed=True) api_manila.share_list.assert_called_with(mock.ANY) api_manila.share_get.assert_called_with(mock.ANY, self.share.id) api_manila.share_delete.assert_called_with( mock.ANY, self.share.id, share_group_id=self.share.share_group_id) self.assertRedirectsNoFollow(res, INDEX_URL) def test_detail_view(self): share_net = test_data.active_share_network rules = [test_data.ip_rule, test_data.user_rule, test_data.cephx_rule] export_locations = test_data.export_locations url = reverse('horizon:project:shares:detail', args=[self.share.id]) self.mock_object( api_manila, "share_network_get", mock.Mock(return_value=share_net)) self.mock_object( api_manila, "share_rules_list", mock.Mock(return_value=rules)) self.mock_object( api_manila, "share_export_location_list", mock.Mock(return_value=export_locations)) res = self.client.get(url) self.assertContains( res, "

Share Details: %s

" % self.share.name, 1, 200) self.assertContains(res, "
%s
" % self.share.name, 1, 200) self.assertContains(res, "
%s
" % self.share.id, 1, 200) self.assertContains(res, "
%s GiB
" % self.share.size, 1, 200) self.assertContains( res, "
%s
" % self.share.share_proto, 1, 200) self.assertContains( res, "
%s
" % self.share.availability_zone, 1, 200) for el in export_locations: self.assertContains(res, "value=\"%s\"" % el.path, 1, 200) self.assertContains( res, "
Preferred: %s
" % el.preferred, 1, 200) self.assertContains( res, "
Is admin only: %s
" % el.is_admin_only, 1, 200) self.assertContains( res, ("
Share Replica ID: %s
" % export_locations[0].share_instance_id), 2, 200) for rule in rules: self.assertContains(res, "
%s
" % rule.access_type, 1, 200) self.assertContains( res, "
Access to: %s
" % rule.access_to, 1, 200) if 'cephx' == rule.access_type: self.assertContains( res, "
Access Key: %s
" % rule.access_key, 1, 200) self.assertContains( res, "
Access Key:
", len(rules) - sum(r.access_type == 'cephx' for r in rules), 200) self.assertContains( res, "
Access Level: rw
", len(rules), 200) self.assertContains( res, "
Status: active
", len(rules), 200) self.assertNoMessages() api_manila.share_rules_list.assert_called_once_with( mock.ANY, self.share.id) api_manila.share_export_location_list.assert_called_once_with( mock.ANY, self.share.id) def test_update_share_get(self): share = test_data.share url = reverse('horizon:project:shares:update', args=[share.id]) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) self.assertNoMessages() self.assertTemplateUsed(res, 'project/shares/update.html') def test_update_share_post(self): self.mock_object(api_manila, "share_update") formData = { 'method': 'UpdateForm', 'name': self.share.name, 'description': self.share.description, 'is_public': False, } url = reverse('horizon:project:shares:update', args=[self.share.id]) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.share_update.assert_called_once_with( mock.ANY, self.share, formData['name'], formData['description'], is_public=formData['is_public']) api_manila.share_get.assert_has_calls( [mock.call(mock.ANY, self.share.id) for i in (1, 2)]) def test_list_rules(self): rules = test_data.share_access_list self.mock_object( api_manila, "share_rules_list", mock.Mock(return_value=rules)) url = reverse( 'horizon:project:shares:manage_rules', args=[self.share.id]) res = self.client.get(url) self.assertEqual(res.status_code, 200) self.assertTemplateUsed(res, 'project/shares/manage_rules.html') api_manila.share_rules_list.assert_called_once_with( mock.ANY, self.share.id) def test_create_rule_get(self): url = reverse('horizon:project:shares:rule_add', args=[self.share.id]) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) self.assertNoMessages() self.assertTemplateUsed(res, 'project/shares/rule_add.html') def test_create_rule_post(self): url = reverse('horizon:project:shares:rule_add', args=[self.share.id]) self.mock_object(api_manila, "share_allow") formData = { 'access_type': 'user', 'method': 'CreateForm', 'access_to': 'someuser', 'access_level': 'rw', 'metadata': {}, } res = self.client.post(url, formData) api_manila.share_allow.assert_called_once_with( mock.ANY, self.share.id, access_type=formData['access_type'], access_to=formData['access_to'], access_level=formData['access_level'], metadata=formData['metadata']) self.assertRedirectsNoFollow( res, reverse('horizon:project:shares:manage_rules', args=[self.share.id]) ) def test_delete_rule(self): rule = test_data.ip_rule formData = {'action': 'rules__delete__%s' % rule.id} self.mock_object(api_manila, "share_deny") self.mock_object( api_manila, "share_rules_list", mock.Mock(return_value=[rule])) url = reverse( 'horizon:project:shares:manage_rules', args=[self.share.id]) self.client.post(url, formData) api_manila.share_deny.assert_called_with( mock.ANY, self.share.id, rule.id) api_manila.share_rules_list.assert_called_with(mock.ANY, self.share.id) def test_update_share_rule_metadata_get(self): rule = test_data.user_rule shares_list = test_data.shares_list rules = test_data.share_access_list url = reverse( 'horizon:project:shares:update_rule_metadata', args=[rule.id]) self.mock_object( api_manila, "share_rules_list", mock.Mock(return_value=rules)) self.mock_object( api_manila, "share_rule_get", mock.Mock(return_value=rule)) self.mock_object( api_manila, "share_list", mock.Mock( return_value=shares_list)) res = self.client.get(url) api_manila.share_rule_get.assert_called_once_with(mock.ANY, rule.id) self.assertNoMessages() self.assertTemplateUsed( res, 'project/shares/update_rule_metadata.html') def test_update_share_rule_metadata_post(self): rule = test_data.user_rule data = { 'metadata': 'aaa=ccc', } form_data = { 'metadata': {'aaa': 'ccc'}, } url = reverse( 'horizon:project:shares:update_rule_metadata', args=[rule.id]) self.mock_object( api_manila, "share_list", mock.Mock( return_value=test_data.shares_list)) self.mock_object( api_manila, "share_rules_list", mock.Mock( return_value=test_data.share_access_list)) self.mock_object( api_manila, "share_rule_get", mock.Mock(return_value=rule)) self.mock_object(api_manila, "share_rule_set_metadata") self.client.post(url, data) api_manila.share_rule_set_metadata.assert_called_once_with( mock.ANY, rule, form_data['metadata']) def test_resize_share_get(self): share = test_data.share url = reverse('horizon:project:shares:resize', args=[share.id]) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) self.assertNoMessages() self.assertTemplateUsed(res, 'project/shares/resize.html') def test_resize_share_open_form_successfully(self): self.share.size = 5 url = reverse('horizon:project:shares:resize', args=[self.share.id]) self.mock_object(api_manila, "share_resize") response = self.client.get(url) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'project/shares/resize.html') api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) self.assertFalse(api_manila.share_resize.called) api_manila.tenant_absolute_limits.assert_called_once_with(mock.ANY) def test_resize_share_get_with_api_exception(self): url = reverse('horizon:project:shares:resize', args=[self.share.id]) self.mock_object(api_manila, "share_resize") self.mock_object( api_manila, "share_get", mock.Mock(return_value=Exception('Fake share NotFound exception'))) response = self.client.get(url) self.assertEqual(404, response.status_code) self.assertTemplateNotUsed( response, 'project/shares/shares/resize.html') self.assertFalse(api_manila.share_resize.called) api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) self.assertFalse(api_manila.tenant_absolute_limits.called) @ddt.data(6, 54, 1, 2, 21) def test_resize_share_post_successfully(self, new_size): self.share.size = 5 form_data = {'new_size': new_size, 'orig_size': self.share.size} usage_limit = { 'maxTotalShareGigabytes': self.share.size + 50, 'totalShareGigabytesUsed': self.share.size, } url = reverse('horizon:project:shares:resize', args=[self.share.id]) self.mock_object(api_manila, "share_resize") self.mock_object( api_manila, 'tenant_absolute_limits', mock.Mock(return_value=usage_limit)) response = self.client.post(url, form_data) self.assertEqual(302, response.status_code) self.assertTemplateNotUsed( response, 'project/shares/resize.html') calls = [ mock.call(mock.ANY, self.share.id), mock.call(mock.ANY, self.share.id)] api_manila.share_get.assert_has_calls(calls) api_manila.share_resize.assert_called_once_with( mock.ANY, self.share.id, form_data['new_size'], form_data['orig_size']) api_manila.tenant_absolute_limits.assert_called_once_with(mock.ANY) self.assertRedirectsNoFollow(response, INDEX_URL) @ddt.data(5, 56, 0, -1) def test_resize_share_post_with_invalid_value(self, new_size): self.share.size = 5 form_data = {'new_size': new_size, 'orig_size': self.share.size} url = reverse('horizon:project:shares:resize', args=[self.share.id]) usage_limit = { 'maxTotalShareGigabytes': self.share.size + 50, 'totalShareGigabytesUsed': self.share.size, } self.mock_object(api_manila, "share_resize") self.mock_object( api_manila, 'tenant_absolute_limits', mock.Mock(return_value=usage_limit)) response = self.client.post(url, form_data) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'project/shares/resize.html') self.assertFalse(api_manila.share_resize.called) api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) api_manila.tenant_absolute_limits.assert_called_with(mock.ANY) def test_resize_share_post_with_api_exception(self): self.share.size = 5 form_data = {'new_size': 30, 'orig_size': self.share.size} url = reverse('horizon:project:shares:resize', args=[self.share.id]) self.mock_object( api_manila, "share_resize", mock.Mock(return_value=Exception('Fake API exception'))) response = self.client.post(url, form_data) self.assertEqual(302, response.status_code) self.assertTemplateNotUsed( response, 'project/shares/resize.html') api_manila.share_resize.assert_called_once_with( mock.ANY, self.share.id, form_data['new_size'], form_data['orig_size']) calls = [ mock.call(mock.ANY, self.share.id), mock.call(mock.ANY, self.share.id)] api_manila.share_get.assert_has_calls(calls) api_manila.tenant_absolute_limits.assert_called_once_with(mock.ANY) self.assertRedirectsNoFollow(response, INDEX_URL) def test_revert_to_snapshot_get_success(self): snapshots = [ type('FakeSnapshot', (object, ), {'name': s_n, 'id': s_id, 'created_at': c_at}) for s_n, s_id, c_at in ( ('foo_name', 'foo_id', '2017-04-20T12:31:14.000000'), ('bar_name', 'bar_id', '2017-04-20T12:31:16.000000')) ] url = reverse('horizon:project:shares:revert', args=[self.share.id]) self.mock_object(api_manila, "share_revert") self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=snapshots)) res = self.client.get(url) api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) api_manila.share_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'share_id': self.share.id}) api_manila.share_revert.assert_not_called() self.assertNoMessages() self.assertTemplateUsed(res, 'project/shares/revert.html') def test_revert_to_snapshot_post_success(self): snapshots = [ type('FakeSnapshot', (object, ), {'name': s_n, 'id': s_id, 'created_at': c_at}) for s_n, s_id, c_at in ( ('foo_name', 'foo_id', '2017-04-20T12:31:14.000000'), ('bar_name', 'bar_id', '2017-04-20T12:31:16.000000'), ('quuz_name', 'quuz_id', '2017-04-20T12:31:13.000000')) ] url = reverse('horizon:project:shares:revert', args=[self.share.id]) self.mock_object(api_manila, "share_revert") self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=snapshots)) data = {'snapshot': snapshots[1].id} res = self.client.post(url, data) api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) api_manila.share_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'share_id': self.share.id}) api_manila.share_revert.assert_called_once_with( mock.ANY, self.share.id, data['snapshot']) self.assertNoMessages() self.assertTemplateNotUsed(res, 'project/shares/revert.html') self.assertRedirectsNoFollow(res, INDEX_URL) def test_revert_to_snapshot_share_not_found(self): url = reverse("horizon:project:shares:revert", args=[self.share.id]) self.mock_object(api_manila, "share_revert") api_manila.share_get.side_effect = Exception( 'Fake share NotFound exception') self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[])) res = self.client.get(url) self.assertEqual(404, res.status_code) self.assertTemplateNotUsed( res, 'project/shares/revert.html') api_manila.share_revert.assert_not_called() api_manila.share_snapshot_list.assert_not_called() api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) def test_revert_to_snapshot_failed(self): snapshots = [ type('FakeSnapshot', (object, ), {'name': s_n, 'id': s_id, 'created_at': c_at}) for s_n, s_id, c_at in ( ('foo_name', 'foo_id', '2017-04-20T12:31:14.000000'), ('bar_name', 'bar_id', '2017-04-20T12:31:16.000000'), ('quuz_name', 'quuz_id', '2017-04-20T12:31:13.000000')) ] url = reverse('horizon:project:shares:revert', args=[self.share.id]) self.mock_object( api_manila, "share_revert", mock.Mock(side_effect=Exception('Fake reverting error'))) self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=snapshots)) data = {'snapshot': snapshots[1].id} res = self.client.post(url, data) self.assertEqual(302, res.status_code) api_manila.share_get.assert_called_once_with(mock.ANY, self.share.id) api_manila.share_snapshot_list.assert_called_once_with( mock.ANY, search_opts={'share_id': self.share.id}) api_manila.share_revert.assert_called_once_with( mock.ANY, self.share.id, data['snapshot']) self.assertTemplateNotUsed(res, 'project/shares/revert.html') self.assertRedirectsNoFollow(res, INDEX_URL) def test_update_share_metadata_get(self): share = test_data.share_with_metadata url = reverse( 'horizon:project:shares:update_metadata', args=[share.id]) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.get(url) api_manila.share_get.assert_called_once_with(mock.ANY, share.id) self.assertNoMessages() self.assertTemplateUsed( res, 'project/shares/update_metadata.html') def test_update_share_metadata_post(self): share = test_data.share_with_metadata data = { 'metadata': 'aaa=ccc', } form_data = { 'metadata': {'aaa': 'ccc'}, } url = reverse( 'horizon:project:shares:update_metadata', args=[share.id]) self.mock_object( api_manila, "share_get", mock.Mock(return_value=share)) self.mock_object(api_manila, "share_set_metadata") self.mock_object( neutron, "is_service_enabled", mock.Mock(return_value=[True])) res = self.client.post(url, data) api_manila.share_set_metadata.assert_called_once_with( mock.ANY, share, form_data['metadata']) self.assertRedirectsNoFollow(res, INDEX_URL) @ddt.data((True, True), (True, False), (False, False)) @ddt.unpack def test_enable_public_share_creation(self, enable_public_shares, is_public): def _get_form(**kwargs): return forms.CreateForm(self.request, **kwargs) self.mock_object( api_manila, "share_create", mock.Mock(return_value=self.share)) self.mock_object( api_manila, "share_snapshot_list", mock.Mock(return_value=[])) self.mock_object( api_manila, "share_network_list", mock.Mock(return_value=[test_data.active_share_network])) self.mock_object( api_manila, "share_type_list", mock.Mock(return_value=[self.fake_share_type, ])) self.mock_object( api_manila, "availability_zone_list", mock.Mock(return_value=[self.FakeAZ('fake_az'), ])) data = { 'name': 'new_share', 'description': 'This is test share', 'method': 'CreateForm', 'share_network': test_data.active_share_network.id, 'size': 1, 'share_proto': 'NFS', 'share_type': 'fake', 'share-network-choices-fake': test_data.active_share_network.id, 'availability_zone': 'fake_az', 'metadata': 'key=value', 'snapshot_id': None, } if enable_public_shares: data.update({'is_public': is_public}) with self.settings(OPENSTACK_MANILA_FEATURES={ 'enable_public_shares': enable_public_shares}): form = _get_form() result = form.handle(self.request, data) self.assertTrue(result) self.assertEqual( enable_public_shares, form.enable_public_shares) if enable_public_shares: self.assertIn("is_public", form.fields) self.assertTrue(form.fields["is_public"]) else: self.assertNotIn("is_public", form.fields) api_manila.share_create.assert_called_once_with( self.request, availability_zone=data['availability_zone'], description=data['description'], is_public=is_public, metadata=utils.parse_str_meta(data['metadata'])[0], name=data['name'], proto=data['share_proto'], share_group_id=None, share_network=test_data.active_share_network.id, share_type=data['share_type'], size=data['size'], snapshot_id=data['snapshot_id'], ) horizon_messages.success.assert_called_once_with( self.request, mock.ANY) @ddt.data((True, True), (True, False), (False, False)) @ddt.unpack def test_enable_public_share_update(self, enable_public_shares, is_public): def _get_form(initial): kwargs = { 'prefix': None, 'initial': initial, } return forms.UpdateForm(self.request, **kwargs) initial = {'share_id': 'fake_share_id'} self.mock_object( api_manila, "share_update", mock.Mock(return_value=self.share)) data = { 'name': 'old_share', 'description': 'This is test share', } if enable_public_shares: data.update({'is_public': is_public}) with self.settings(OPENSTACK_MANILA_FEATURES={ 'enable_public_shares': enable_public_shares}): form = _get_form(initial) result = form.handle(self.request, data) self.assertTrue(result) self.assertEqual( enable_public_shares, form.enable_public_shares) if enable_public_shares: self.assertIn("is_public", form.fields) self.assertTrue(form.fields["is_public"]) else: self.assertNotIn("is_public", form.fields) api_manila.share_update.assert_called_once_with( self.request, self.share, data['name'], data['description'], is_public=is_public, ) horizon_messages.success.assert_called_once_with( self.request, mock.ANY) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/test_data.py0000664000175000017500000005300100000000000024671 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manilaclient.v2 import messages from manilaclient.v2 import security_services from manilaclient.v2 import share_access_rules from manilaclient.v2 import share_export_locations from manilaclient.v2 import share_group_snapshots from manilaclient.v2 import share_group_types from manilaclient.v2 import share_groups from manilaclient.v2 import share_instances from manilaclient.v2 import share_networks from manilaclient.v2 import share_replicas from manilaclient.v2 import share_servers from manilaclient.v2 import share_snapshot_export_locations from manilaclient.v2 import share_snapshots from manilaclient.v2 import share_types from manilaclient.v2 import shares class FakeAPIClient(object): client = "fake_client" share = shares.Share( shares.ShareManager(FakeAPIClient), {'id': "11023e92-8008-4c8b-8059-7f2293ff3887", 'status': 'available', 'size': 40, 'name': 'Share name', 'description': 'Share description', 'is_public': False, 'share_proto': 'NFS', 'metadata': {}, 'created_at': '2014-01-27 10:30:00', 'share_server_id': '1', 'share_network_id': '7f3d1c33-8d00-4511-29df-a2def31f3b5d', 'availability_zone': 'Test AZ', 'replication_type': 'readable', 'share_group_id': 'fake_share_group_id', 'mount_snapshot_support': False}) nameless_share = shares.Share( shares.ShareManager(FakeAPIClient), {'id': "4b069dd0-6eaa-4272-8abc-5448a68f1cce", 'status': 'available', 'size': 10, 'name': '', 'description': '', 'share_proto': 'NFS', 'export_location': "/dev/hda", 'metadata': {}, 'created_at': '2010-11-21 18:34:25', 'share_type': 'vol_type_1', 'share_server_id': '1', 'share_network_id': '7f3d1c33-8d00-4511-29df-a2def31f3b5d', 'availability_zone': 'Test AZ', 'replication_type': None, 'mount_snapshot_support': False}) share_with_metadata = shares.Share( shares.ShareManager(FakeAPIClient), {'id': "0ebb3748-c1dr-4bb6-8315-0354e7691fff", 'status': 'available', 'size': 40, 'name': 'Share with metadata', 'description': 'Share description', 'share_proto': 'NFS', 'metadata': {'aaa': 'bbb'}, 'created_at': '2016-06-31 00:00:00', 'share_server_id': '1', 'share_network_id': '7f3d1c33-8d00-4511-29df-a2def31f3b5d', 'availability_zone': 'Test AZ', 'replication_type': 'readable', 'mount_snapshot_support': False}) other_share = shares.Share( shares.ShareManager(FakeAPIClient), {'id': "21023e92-8008-1234-8059-7f2293ff3889", 'status': 'in-use', 'size': 10, 'name': 'my_share', 'description': '', 'share_proto': 'NFS', 'metadata': {}, 'created_at': '2013-04-01 10:30:00', 'share_type': None, 'share_server_id': '1', 'share_network_id': '7f3d1c33-8d00-4511-29df-a2def31f3b5d', 'availability_zone': 'Test AZ', 'replication_type': 'readable', 'mount_snapshot_support': False}) shares_list = [share, nameless_share, other_share] share_replica = share_replicas.ShareReplica( share_replicas.ShareReplicaManager(FakeAPIClient), {'id': '11023e92-8008-4c8b-8059-replica00001', 'availability_zone': share.availability_zone, 'host': 'fake_host_1', 'share_id': share.id, 'status': 'available', 'replica_state': 'active', 'created_at': '2016-07-19 19:46:13', 'updated_at': '2016-07-19 19:47:14'} ) share_replica2 = share_replicas.ShareReplica( share_replicas.ShareReplicaManager(FakeAPIClient), {'id': '11023e92-8008-4c8b-8059-replica00002', 'availability_zone': share.availability_zone, 'host': 'fake_host_2', 'share_id': share.id, 'status': 'available', 'replica_state': 'in_sync', 'created_at': '2016-07-19 20:46:13', 'updated_at': '2016-07-19 20:47:14'} ) share_replica3 = share_replicas.ShareReplica( share_replicas.ShareReplicaManager(FakeAPIClient), {'id': '11023e92-8008-4c8b-8059-replica00003', 'availability_zone': share.availability_zone, 'host': 'fake_host_3', 'share_id': share.id, 'status': 'available', 'replica_state': 'active', 'created_at': '2016-07-19 21:46:13', 'updated_at': '2016-07-19 21:47:14'} ) share_mount_snapshot = shares.Share( shares.ShareManager(FakeAPIClient), {'id': "11023e92-8008-4c8b-8059-7f2293ff3888", 'status': 'available', 'size': 40, 'name': 'Share name', 'description': 'Share description', 'share_proto': 'NFS', 'metadata': {}, 'created_at': '2014-01-27 10:30:00', 'share_server_id': '1', 'share_network_id': '7f3d1c33-8d00-4511-29df-a2def31f3b5d', 'availability_zone': 'Test AZ', 'replication_type': 'readable', 'mount_snapshot_support': True}) admin_export_location = share_export_locations.ShareExportLocation( share_export_locations.ShareExportLocationManager(FakeAPIClient), {'id': '6921e862-88bc-49a5-a2df-efeed9acd583', 'path': '1.1.1.1:/path/to/admin/share', 'preferred': False, 'is_admin_only': True, 'share_instance_id': 'e1c2d35e-fe67-4028-ad7a-45f668732b1d'} ) user_export_location = share_export_locations.ShareExportLocation( share_export_locations.ShareExportLocationManager(FakeAPIClient), {'id': 'b6bd76ce-12a2-42a9-a30a-8a43b503867d', 'path': '2.2.2.2:/path/to/user/share', 'preferred': True, 'is_admin_only': False, 'share_instance_id': 'e1c2d35e-fe67-4028-ad7a-45f668732b1d'} ) export_locations = [admin_export_location, user_export_location] admin_snapshot_export_locations = [ share_snapshot_export_locations.ShareSnapshotExportLocation( share_snapshot_export_locations.ShareSnapshotExportLocationManager( FakeAPIClient), {'id': '6921e862-88bc-49a5-a2df-efeed9acd584', 'path': '1.1.1.1:/path/to/admin/share', 'is_admin_only': True, 'share_snapshot_instance_id': 'e1c2d35e-fe67-4028-ad7a-45f668732b1e'} ), share_snapshot_export_locations.ShareSnapshotExportLocation( share_snapshot_export_locations.ShareSnapshotExportLocationManager( FakeAPIClient), {'id': '6921e862-88bc-49a5-a2df-efeed9acd585', 'path': '1.1.1.2:/path/to/admin/share', 'is_admin_only': False, 'share_snapshot_instance_id': 'e1c2d35e-fe67-4028-ad7a-45f668732b1f'} ) ] user_snapshot_export_locations = [ share_snapshot_export_locations.ShareSnapshotExportLocation( share_snapshot_export_locations.ShareSnapshotExportLocationManager( FakeAPIClient), {'id': 'b6bd76ce-12a2-42a9-a30a-8a43b503867e', 'path': '1.1.1.1:/path/to/user/share_snapshot'} ), share_snapshot_export_locations.ShareSnapshotExportLocation( share_snapshot_export_locations.ShareSnapshotExportLocationManager( FakeAPIClient), {'id': 'b6bd76ce-12a2-42a9-a30a-8a43b503867f', 'path': '1.1.1.2:/not/too/long/path/to/user/share_snapshot'} ) ] ip_rule = share_access_rules.ShareAccessRule( share_access_rules.ShareAccessRuleManager(FakeAPIClient), {'id': 'ca8b755c-fe13-497f-81d0-fd2f13a30a78', 'access_level': 'rw', 'access_to': '1.1.1.1', 'access_type': 'ip', 'state': 'active', 'access_key': '', 'created_at': '2021-03-03T14:29:41.000000', 'updated_at': '', "metadata": {}, }) user_rule = share_access_rules.ShareAccessRule( share_access_rules.ShareAccessRuleManager(FakeAPIClient), {'id': '0837072-c49e-11e3-bd64-60a44c371189', 'access_level': 'rw', 'access_to': 'someuser', 'access_type': 'user', 'state': 'active', 'access_key': '', 'created_at': '2021-03-03T14:29:41.000000', 'updated_at': '', 'metadata': {'abc': 'ddd'}, }) cephx_rule = share_access_rules.ShareAccessRule( share_access_rules.ShareAccessRuleManager(FakeAPIClient), {'id': '235481bc-1a84-11e6-9666-68f728a0492e', 'access_level': 'rw', 'access_to': 'alice', 'access_type': 'cephx', 'state': 'active', 'access_key': 'AQAdFCNYDCapMRAANuK/CiEZbog2911a+t5dcQ==', 'created_at': '2021-03-03T14:29:41.000000', 'updated_at': '', 'metadata': {'test': 'true'}, }) share_access_list = [user_rule, cephx_rule, ip_rule] snapshot = share_snapshots.ShareSnapshot( share_snapshots.ShareSnapshotManager(FakeAPIClient), {'id': '5f3d1c33-7d00-4511-99df-a2def31f3b5d', 'name': 'test snapshot', 'description': 'share snapshot', 'size': 40, 'status': 'available', 'share_id': '11023e92-8008-4c8b-8059-7f2293ff3887'}) snapshot_mount_support = share_snapshots.ShareSnapshot( share_snapshots.ShareSnapshotManager(FakeAPIClient), {'id': '5f3d1c33-7d00-4511-99df-a2def31f3b5e', 'name': 'test snapshot', 'description': 'share snapshot', 'size': 40, 'status': 'available', 'share_id': '11023e92-8008-4c8b-8059-7f2293ff3888'}) inactive_share_network = share_networks.ShareNetwork( share_networks.ShareNetworkManager(FakeAPIClient), {'id': '6f3d1c33-8d00-4511-29df-a2def31f3b5d', 'name': 'test_share_net', 'description': 'test share network', 'status': 'INACTIVE', 'neutron_net_id': 'fake_neutron_net_id', 'neutron_subnet_id': 'fake_neutron_subnet_id'}) active_share_network = share_networks.ShareNetwork( share_networks.ShareNetworkManager(FakeAPIClient), { "id": "1324e7d3-fba8-45e4-bb37-b59c12eb06dc", "name": "net_my1", "project_id": "16e1ab15c35a457e9c2b2aa189f544e1", "created_at": "2019-10-02T17:49:43.000000", "description": "This is test share network", "security_service_update_support": True, "status": "active", "share_network_subnets": [ { "id": "e4db03dc-6041-4c6a-a8f9-80bb4141a1eb", "availability_zone": None, "created_at": "2019-10-02T17:49:43.000000", "updated_at": "2019-10-03T12:17:39.000000", "segmentation_id": None, "neutron_net_id": "62187648-6617-4509-a780-ffc973a7fe43", "neutron_subnet_id": "2276888a-27c1-47c2-82a0-ea33050128b5", "ip_version": 4, "cidr": "172.24.5.0/24", "network_type": "flat", "mtu": 1500, "gateway": "172.24.5.1", }, { "id": "e4db03dc-6041-4c6a-a8f9-80bb4141a1en", "availability_zone": "manila-zone-0", "created_at": "2019-10-02T17:49:43.000000", "updated_at": "2019-10-03T12:17:39.000000", "segmentation_id": None, "neutron_net_id": "62187648-6617-4509-a780-ffc973a7f333", "neutron_subnet_id": "2276888a-27c1-47c2-82a0-ea3305012905", "ip_version": 4, "cidr": "172.24.5.0/24", "network_type": "flat", "mtu": 1500, "gateway": "172.24.5.1", }, ], } ) sec_service = security_services.SecurityService( security_services.SecurityServiceManager(FakeAPIClient), {'id': '7f3d1c33-8d10-4511-29df-a2def31f3b5d', 'server': '1.1.1.1', 'dns_ip': '2.2.2.2', 'ou': 'someOU', 'user': 'someuser', 'password': 'somepass', 'type': 'active_directory', 'name': 'test-sec-service', 'description': 'test security service', 'domain': 'testdomain', }) share_instance = share_instances.ShareInstance( share_instances.ShareInstanceManager(FakeAPIClient), {'id': 'fake_share_instance_no_ss_id', 'status': 'available', 'host': 'host1@backend1#pool1', 'availability_zone': 'zone1', 'share_id': 'fake_share_id_1', 'share_network_id': 'fake_share_network_id_1', 'share_server_id': 'fake_share_server_id_1', 'created_at': '2016-04-26 13:14:15'} ) share_instance_no_ss = share_instances.ShareInstance( share_instances.ShareInstanceManager(FakeAPIClient), {'id': 'fake_share_instance_id', 'status': 'available', 'host': 'host2@backend2#pool2', 'availability_zone': 'zone2', 'share_id': 'fake_share_id_2', 'share_network_id': None, 'share_server_id': None, 'created_at': '2016-04-26 14:15:16'} ) share_server = share_servers.ShareServer( share_servers.ShareServerManager(FakeAPIClient), {'id': 'fake_share_server_id1', 'status': 'active', 'share_network_id': 'fake_share_network_id1', 'share_network_name': 'fake_share_network_name1', 'project_id': 'fake_project_id1', 'backend_details': { 'foo_key': 'foo_value', 'bar_key_foo': 'bar_value_foo', }, 'host': 'fakehost1@fakebackend1#fakepool1'} ) share_server_errored = share_servers.ShareServer( share_servers.ShareServerManager(FakeAPIClient), {'id': 'fake_share_server_id2', 'status': 'error', 'share_network_id': 'fake_share_network_id2', 'share_network_name': 'fake_share_network_name2', 'project_id': 'fake_project_id2', 'backend_details': {}, 'host': 'fakehost2@fakebackend2#fakepool2'} ) share_type = share_types.ShareType( share_types.ShareTypeManager(FakeAPIClient), {'id': 'share-type-id1', 'name': 'test-share-type1', 'share_type_access:is_public': True, 'extra_specs': { 'snapshot_support': True, 'driver_handles_share_servers': False} } ) share_type_private = share_types.ShareType( share_types.ShareTypeManager(FakeAPIClient), {'id': 'share-type-id2', 'name': 'test-share-type2', 'share_type_access:is_public': False, 'extra_specs': {'driver_handles_share_servers': False}} ) share_type_dhss_true = share_types.ShareType( share_types.ShareTypeManager(FakeAPIClient), {'id': 'share-type-id3', 'name': 'test-share-type3', 'share_type_access:is_public': True, 'extra_specs': {'driver_handles_share_servers': True}} ) share_type_alt = share_types.ShareType( share_types.ShareTypeManager(FakeAPIClient), {'id': 'share-type-id4', 'name': 'test-share-type4', 'share_type_access:is_public': True, 'extra_specs': { 'snapshot_support': True, 'driver_handles_share_servers': False} } ) share_group_type = share_group_types.ShareGroupType( share_group_types.ShareGroupTypeManager(FakeAPIClient), {'id': 'fake_share_group_type_id1', 'name': 'fake_share_group_type_name', 'share_types': [share_type.id], 'group_specs': {'k1': 'v1', 'k2': 'v2'}, 'is_public': True} ) share_group_type_private = share_group_types.ShareGroupType( share_group_types.ShareGroupTypeManager(FakeAPIClient), {'id': 'fake_private_share_group_type_id2', 'name': 'fake_private_share_group_type_name', 'share_types': [share_type.id, share_type_private.id], 'group_specs': {'k1': 'v1', 'k2': 'v2'}, 'is_public': False} ) share_group_type_dhss_true = share_group_types.ShareGroupType( share_group_types.ShareGroupTypeManager(FakeAPIClient), {'id': 'fake_share_group_type_id3', 'name': 'fake_share_group_type_name', 'share_types': [share_type_dhss_true.id], 'group_specs': {'k3': 'v3', 'k4': 'v4'}, 'is_public': True} ) share_group_type_alt = share_group_types.ShareGroupType( share_group_types.ShareGroupTypeManager(FakeAPIClient), {'id': 'fake_share_group_type_id4', 'name': 'fake_share_group_type_name', 'share_types': [share_type_alt.id], 'group_specs': {'k5': 'v5', 'k6': 'v6'}, 'is_public': True} ) share_group = share_groups.ShareGroup( share_groups.ShareGroupManager(FakeAPIClient), {'id': 'fake_share_group_id', 'name': 'fake_share_group_name', 'description': 'fake sg description', 'status': 'available', 'share_types': [share_type.id], 'share_group_type_id': share_group_type.id, 'source_share_group_snapshot_id': None, 'share_network_id': None, 'share_server_id': None, 'availability_zone': None, 'host': 'fake_host_987654321', 'consistent_snapshot_support': None, 'created_at': '2017-05-31T13:36:15.000000', 'project_id': 'fake_project_id_987654321'} ) share_group_nameless = share_groups.ShareGroup( share_groups.ShareGroupManager(FakeAPIClient), {'id': 'fake_nameless_share_group_id', 'name': None, 'status': 'available', 'share_types': [share_type.id], 'share_group_type_id': share_group_type.id, 'source_share_group_snapshot_id': None, 'share_network_id': None, 'share_server_id': None, 'availability_zone': None, 'host': 'fake_host_987654321', 'consistent_snapshot_support': None, 'created_at': '2017-05-31T13:36:15.000000', 'project_id': 'fake_project_id_987654321'} ) share_group_dhss_true = share_groups.ShareGroup( share_groups.ShareGroupManager(FakeAPIClient), {'id': 'fake_dhss_true_share_group_id', 'name': 'fake_dhss_true_share_group_name', 'status': 'available', 'share_types': [share_type_dhss_true.id], 'share_group_type_id': share_group_type_dhss_true.id, 'source_share_group_snapshot_id': None, 'share_network_id': 'fake_share_network_id', 'share_server_id': 'fake_share_server_id', 'availability_zone': None, 'host': 'fake_host_987654321', 'consistent_snapshot_support': 'pool', 'created_at': '2017-05-31T23:59:59.000000', 'project_id': 'fake_project_id_987654321'} ) share_group_snapshot = share_group_snapshots.ShareGroupSnapshot( share_group_snapshots.ShareGroupSnapshotManager(FakeAPIClient), {'id': 'fake_share_group_snapshot_id_1', 'name': 'fake_share_group_snapshot_name', 'status': 'available', 'share_group_id': share_group.id, 'description': 'fake sgs description', 'created_at': '2017-06-01T13:13:13.000000', 'project_id': 'fake_project_id_987654321', 'members': [ {'share_id': 'fake_share_id_1', 'id': 'fake_ssi_id_1', 'size': 1}, {'share_id': 'fake_share_id_2', 'id': 'fake_ssi_id_2', 'size': 2}, ]} ) share_group_snapshot_nameless = share_group_snapshots.ShareGroupSnapshot( share_group_snapshots.ShareGroupSnapshotManager(FakeAPIClient), {'id': 'fake_share_group_snapshot_id_2_nameless', 'name': None, 'status': 'available', 'share_group_id': share_group_nameless.id, 'description': 'fake nameless sgs description', 'created_at': '2017-06-02T14:14:14.000000', 'project_id': 'fake_project_id_987654321', 'members': []} ) # Manila Limits limits = {"totalSharesUsed": 1, "totalShareSnapshotsUsed": 1, "totalShareGigabytesUsed": 500, "totalSnapshotGigabytesUsed": 500, "maxTotalShares": 10, "maxTotalShareSnapshots": 10, "maxTotalShareGigabytes": 1000, "maxTotalSnapshotGigabytes": 1000, } limits_negative = {"totalSharesUsed": 10, "totalShareSnapshotsUsed": 10, "totalShareGigabytesUsed": 1000, "totalSnapshotGigabytesUsed": 1000, "maxTotalShares": 10, "maxTotalShareSnapshots": 10, "maxTotalShareGigabytes": 1000, "maxTotalSnapshotGigabytes": 1000, } # Manila User Messages fake_message_1 = messages.Message( messages.MessageManager(FakeAPIClient), {'resource_id': "351cc796-2d79-4a08-b878-a8ed933b6b68", 'message_level': 'ERROR', 'user_message': 'allocate host: No storage could be allocated for' ' this share request. Trying again with a different' ' size or share type may succeed.', 'expires_at': '2017-07-10T10:27:43.000000', 'id': '4b319d29-d5b7-4b6e-8e7c-8d6e53f3c3d5', 'created_at': '2017-07-10T10:26:43.000000', 'detail_id': '002', 'request_id': 'req-24e7ccb6-a7d5-4ddd-a8e4-d8f72a4509c8', 'project_id': '2e3de76b49b444fd9dc7ca9f7048ce6b', 'resource_type': 'SHARE', 'action_id': '001'}) fake_message_2 = messages.Message( messages.MessageManager(FakeAPIClient), {'resource_id': "25b4c0cc-e711-4c6f-b9fd-72d6b5c62bce", 'message_level': 'ERROR', 'user_message': 'Driver does not expect share-network to be provided ' 'with current configuration.', 'expires_at': '2018-09-10T09:37:45.000000', 'id': 'd01d03ee-7758-4175-a6b5-853329dd2f4e', 'created_at': '2018-09-10T09:36:45.000000', 'detail_id': '003', 'request_id': 'req-fa568ab0-d6b3-4b32-899d-637ee006fed4', 'project_id': '2e3de76b49b444fd9dc7ca9f7048ce6b', 'resource_type': 'SHARE', 'action_id': '002'}) fake_message_3 = messages.Message( messages.MessageManager(FakeAPIClient), {'resource_id': "4befdc84-2796-44e1-8645-14b651bfb787", 'message_level': 'ERROR', 'user_message': 'Share has no replica with "replica_state" ' 'set to "active"', 'expires_at': '2020-09-09T22:37:13.000000', 'id': '1e1c493f-d07d-48e9-93a8-ef5ad4b8ca8a', 'created_at': '2020-09-09T22:36:13.000000', 'detail_id': '004', 'request_id': 'req-29449bc8-d0ec-4d6b-b37c-85d0f04251b1', 'project_id': '2e3de76b49b444fd9dc7ca9f7048ce6b', 'resource_type': 'SHARE_REPLICA', 'action_id': '002'}) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/tests.py0000664000175000017500000000610600000000000024067 0ustar00zuulzuul00000000000000# Copyright (c) 2014 NetApp, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import reverse from django.utils import translation from unittest import mock from manila_ui.dashboards.project import shares from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:shares:index') class PieChartsTests(test.TestCase): def test_get_context_data(self): limits = { "totalSharesUsed": 1, "totalShareGigabytesUsed": 2, "totalShareNetworksUsed": 3, "totalShareSnapshotsUsed": 4, "totalSnapshotGigabytesUsed": 5, "maxTotalShares": 6, "maxTotalShareGigabytes": 7, "maxTotalShareNetworks": 8, "maxTotalShareSnapshots": 9, "maxTotalSnapshotGigabytes": 10, } existing_chart_name = "Foo" existing_chart = { "name": translation.gettext_lazy(existing_chart_name), "used": 11, "max": 13, "text": "fake_text", } class ParentViewInstance(mock.MagicMock): def get_context_data(self, **kwargs): return {"charts": [existing_chart]} class ViewInstance(ParentViewInstance): usage = type("FakeUsage", (object, ), {"limits": limits}) view_instance = ViewInstance() result = shares.get_context_data( view_instance, fook="foov", bark="barv") charts = result.get("charts", []) self.assertEqual(6, len(charts)) expected_charts = { existing_chart_name: { "name": existing_chart_name, "used": existing_chart["used"], "max": existing_chart["max"], "text": existing_chart["text"]}, "Shares": {"name": "Shares", "used": 1, "max": 6, "text": False}, "Share Storage": { "name": "Share Storage", 'used': 2, "max": 7, "text": False}, "Share Networks": { "name": "Share Networks", "used": 3, "max": 8, "text": False}, "Share Snapshots": { "name": "Share Snapshots", "used": 4, "max": 9, "text": False}, "Share Snapshots Storage": { "name": "Share Snapshots Storage", "used": 5, "max": 10, "text": False}, } for chart in charts: name = chart["name"].title() self.assertEqual( {"name": name, "used": chart["used"], "max": chart["max"], "text": chart["text"]}, expected_charts.pop(name, "NotFound") ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/dashboards/project/user_messages/0000775000175000017500000000000000000000000025215 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/user_messages/__init__.py0000664000175000017500000000000000000000000027314 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/project/user_messages/tests.py0000664000175000017500000000773200000000000026742 0ustar00zuulzuul00000000000000# Copyright 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ddt from django.urls import reverse from unittest import mock from horizon import exceptions as horizon_exceptions from manila_ui.api import manila as api_manila from manila_ui.tests.dashboards.project import test_data from manila_ui.tests import helpers as test INDEX_URL = reverse('horizon:project:user_messages:index') @ddt.ddt class UserMessagesViewTests(test.TestCase): @ddt.data(None, Exception('fake')) def test_view(self, exc): message_1 = test_data.fake_message_1 message_2 = test_data.fake_message_2 message_3 = test_data.fake_message_3 fake_message_list = [message_1, message_2, message_3] url = reverse('horizon:project:user_messages:index') self.mock_object( api_manila, "messages_list", mock.Mock(side_effect=exc, return_value=fake_message_list)) self.client.get(url) self.assertNoMessages() api_manila.messages_list.assert_called_once_with(mock.ANY) @ddt.data(None, Exception('fake')) def test_delete_message(self, exc): message = test_data.fake_message_1 formData = {'action': 'user_messages__delete__%s' % message.id} self.mock_object(api_manila, "messages_delete", mock.Mock(side_effect=exc)) self.mock_object( api_manila, "messages_list", mock.Mock(return_value=[message])) res = self.client.post(INDEX_URL, formData) self.assertEqual(res.status_code, 302) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.messages_list.assert_called_once_with(mock.ANY) api_manila.messages_delete.assert_called_once_with( mock.ANY, test_data.fake_message_1.id) @ddt.ddt class UserMessagesDetailViewTests(test.TestCase): def test_detail_view(self): message = test_data.fake_message_1 url = reverse('horizon:project:user_messages:user_messages_detail', args=[message.id]) self.mock_object( api_manila, "messages_get", mock.Mock(return_value=message)) res = self.client.get(url) self.assertContains(res, "

User Message Details: %s

" % message.id, 1, 200) self.assertContains(res, "
%s
" % message.id, 1, 200) self.assertContains(res, "
%s
" % message.action_id, 1, 200) self.assertContains(res, "
%s
" % message.user_message, 1, 200) self.assertContains(res, "
%s
" % message.message_level, 1, 200) self.assertContains(res, "
%s
" % message.resource_type, 1, 200) self.assertContains(res, "
%s
" % message.resource_id, 1, 200) self.assertContains(res, "
%s
" % message.request_id, 1, 200) self.assertNoMessages() api_manila.messages_get.assert_called_once_with( mock.ANY, message.id) def test_detail_view_with_exception(self): message = test_data.fake_message_1 url = reverse( 'horizon:project:user_messages:user_messages_detail', args=[message.id]) self.mock_object( api_manila, "messages_get", mock.Mock(side_effect=horizon_exceptions.NotFound(404))) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL) api_manila.messages_get.assert_called_once_with(mock.ANY, message.id) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/dashboards/test_utils.py0000664000175000017500000000663200000000000023462 0ustar00zuulzuul00000000000000# Copyright (c) 2015 Mirantis, Inc. # 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 ddt from django.forms import ValidationError from manila_ui.dashboards import utils from manila_ui.tests import helpers as base @ddt.ddt class ManilaDashboardsUtilsTests(base.TestCase): @ddt.data( ("", {}, []), (" ", {}, []), ("\n", {}, []), ("f", {}, ["f"]), ("f=b", {"f": "b"}, []), ("foo=bar", {"foo": "bar"}, []), ("\nfoo \n", {}, ["foo"]), ("'foo'=\"bar\"\n'bar'", {"foo": "bar"}, ["bar"]), (" foo= bar ", {"foo": "bar"}, []), ("foo= \" bar\"\n", {"foo": " bar"}, []), ("\n\nset_me_key = 'value with spaces and equality 2=2'\nunset_key ", {"set_me_key": "value with spaces and equality 2=2"}, ["unset_key"]), ("f" * 255, {}, ["f" * 255]), ("f" * 255 + "=" + "b" * 255, {"f" * 255: "b" * 255}, []), ) @ddt.unpack def test_parse_str_meta_success( self, input_data, expect_set_dict, expected_unset_list): set_dict, unset_list = utils.parse_str_meta(input_data) self.assertEqual(expect_set_dict, set_dict) self.assertEqual(expected_unset_list, unset_list) @ddt.data( "a b", "'a b'", "\"a b\"", "f" * 256, "f" * 256 + "=bar", "foo=" + "b" * 256, "\"a b \"", "foo=bar\nfoo", "foo=bar\nfoo=quuz", ) def test_parse_str_meta_validation_error(self, input_data): self.assertRaises(ValidationError, utils.parse_str_meta, input_data) @ddt.data( (({"a": ""}, ), "a = <script>alert('A')/*
b = */</script>"), (({"fookey": "foovalue", "barkey": "barvalue"}, ), "barkey = barvalue
fookey = foovalue"), (({"foo": "barquuz"}, 1, 2), "fo... = ba..."), (({"foo": "barquuz", "zfoo": "zbarquuz"}, 1, 3), "foo = bar..."), (({"foo": "barquuz", "zfoo": "zbarquuz"}, 2, 3), "foo = bar...
zfo... = zba..."), (({"foo": "barquuz", "zfoo": "zbarquuz"}, 3, 3), "foo = bar...
zfo... = zba..."), (({"foo": "barquuz", "zfoo": "zbarquuz"}, 3, 8), "foo = barquuz
zfoo = zbarquuz"), ) @ddt.unpack def test_metadata_to_str(self, input_args, expected_output): result = utils.metadata_to_str(*input_args) self.assertEqual(expected_output, result) @ddt.data( ("ldap", "LDAP"), ("active_directory", "Active Directory"), ("kerberos", "Kerberos"), ("FaKe", "FaKe"), ) @ddt.unpack def test_get_nice_security_service_type(self, input_value, expected_value): security_service = type("FakeSS", (object, ), {"type": input_value})() result = utils.get_nice_security_service_type(security_service) self.assertEqual(expected_value, result) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/helpers.py0000664000175000017500000000411200000000000020602 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import unittest from unittest import mock from manila_ui import api from manila_ui.tests.test_data import utils from openstack_dashboard.test import helpers class ManilaTestsMixin(object): def _setup_test_data(self): super(ManilaTestsMixin, self)._setup_test_data() utils.load_test_data(self) def mock_object(self, obj, attr_name, new_attr=None, **kwargs): """Use python mock to mock an object attribute Mocks the specified objects attribute with the given value. Automatically performs 'addCleanup' for the mock. """ if not new_attr: new_attr = mock.Mock() patcher = mock.patch.object(obj, attr_name, new_attr, **kwargs) patcher.start() # NOTE(vponomaryov): 'self.addCleanup(patcher.stop)' is not called # here, because it is inherited from Horizon project's test class. return new_attr @unittest.skipIf(os.environ.get('SKIP_UNITTESTS', False), "The SKIP_UNITTESTS env variable is set.") class TestCase(ManilaTestsMixin, helpers.TestCase): pass class BaseAdminViewTests(ManilaTestsMixin, helpers.BaseAdminViewTests): pass class APITestCase(ManilaTestsMixin, helpers.APITestCase): def setUp(self): super(APITestCase, self).setUp() self._manilaclient = self.mock_object(api.manila, "manilaclient") self.manilaclient = self._manilaclient.return_value class FakeEntity(object): def __init__(self, id, name): self.id = id self.name = name ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/integration/0000775000175000017500000000000000000000000021113 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/__init__.py0000664000175000017500000000000000000000000023212 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/horizon.conf0000664000175000017500000000070200000000000023451 0ustar00zuulzuul00000000000000[plugin] is_plugin=True plugin_page_path=manila_ui.tests.integration.pages plugin_page_structure='{"Project": {"Share": {"_": ["Shares", "Share Snapshots", "Share Networks", "Security Services", "Share Groups", "Share Group Snapshots"]}}, "Admin": {"Share": {"_": ["Shares", "Share Snapshots", "Share Types", "Share Networks", "Security Services", "Share Servers", "Share Instances", "Share Groups", "Share Group Snapshots", "Share Group Types"]}}}' ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/integration/pages/0000775000175000017500000000000000000000000022212 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/__init__.py0000664000175000017500000000000000000000000024311 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/0000775000175000017500000000000000000000000023302 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/__init__.py0000664000175000017500000000000000000000000025401 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/0000775000175000017500000000000000000000000024404 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/__init__.py0000664000175000017500000000000000000000000026503 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/messagespage.py0000664000175000017500000000134600000000000027426 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import messagespage class MessagesPage(messagespage.MessagesPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/securityservicespage.py0000664000175000017500000000135100000000000031226 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import \ securityservicespage class SecurityservicesPage(securityservicespage.SecurityservicesPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharegroupsnapshotspage.py0000664000175000017500000000140400000000000031734 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import \ sharegroupsnapshotspage as sg_snapshots_page class SharegroupsnapshotsPage(sg_snapshots_page.SharegroupsnapshotsPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharegroupspage.py0000664000175000017500000000131700000000000030157 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import sharegroupspage class SharegroupsPage(sharegroupspage.SharegroupsPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharegroupssnapshotspage.py0000664000175000017500000000140600000000000032121 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import \ sharegroupsnapshotspage as sg_snapshots_page class SharegroupssnapshotsPage(sg_snapshots_page.SharegroupssnapshotsPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharegrouptypespage.py0000664000175000017500000000152500000000000031062 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharegrouptypesPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharegrouptypesPage, self).__init__(driver, conf) self._page_title = "Share Group Types" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/shareinstancespage.py0000664000175000017500000000152100000000000030624 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class ShareinstancesPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(ShareinstancesPage, self).__init__(driver, conf) self._page_title = "Share Instances" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharenetworkspage.py0000664000175000017500000000132700000000000030515 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import sharenetworkspage class SharenetworksPage(sharenetworkspage.SharenetworksPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/shareserverspage.py0000664000175000017500000000130600000000000030327 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class ShareserversPage(basepage.BaseNavigationPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharesnapshotspage.py0000664000175000017500000000133300000000000030660 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import sharesnapshotspage class SharesnapshotsPage(sharesnapshotspage.SharesnapshotsPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharespage.py0000664000175000017500000000127300000000000027103 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from manila_ui.tests.integration.pages.project.share import sharespage class SharesPage(sharespage.SharesPage): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/admin/share/sharetypespage.py0000664000175000017500000000150500000000000030003 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharetypesPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharetypesPage, self).__init__(driver, conf) self._page_title = "Share Types" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8426514 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/0000775000175000017500000000000000000000000023660 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/__init__.py0000664000175000017500000000000000000000000025757 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8466513 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/0000775000175000017500000000000000000000000024762 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/__init__.py0000664000175000017500000000000000000000000027061 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/messagespage.py0000664000175000017500000000154600000000000030006 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class MessagesPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(MessagesPage, self).__init__(driver, conf) self._page_title = "User Messages" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/securityservicespage.py0000664000175000017500000000152700000000000031611 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SecurityservicesPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SecurityservicesPage, self).__init__(driver, conf) self._page_title = "Security Services" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/sharegroupsnapshotspage.py0000664000175000017500000000154100000000000032314 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharegroupsnapshotsPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharegroupsnapshotsPage, self).__init__(driver, conf) self._page_title = "Share Group Snapshots" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/sharegroupspage.py0000664000175000017500000000151000000000000030530 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharegroupsPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharegroupsPage, self).__init__(driver, conf) self._page_title = "Share Groups" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/sharenetworkspage.py0000664000175000017500000000151600000000000031073 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharenetworksPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharenetworksPage, self).__init__(driver, conf) self._page_title = "Share Networks" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/sharesnapshotspage.py0000664000175000017500000000152100000000000031235 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharesnapshotsPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharesnapshotsPage, self).__init__(driver, conf) self._page_title = "Share Snapshots" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/pages/project/share/sharespage.py0000664000175000017500000000147000000000000027460 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests.pages import basepage class SharesPage(basepage.BaseNavigationPage): def __init__(self, driver, conf): super(SharesPage, self).__init__(driver, conf) self._page_title = "Shares" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/integration/test_basic.py0000664000175000017500000001110300000000000023601 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.integration_tests import helpers class TestManilaDashboardInstalled(helpers.TestCase): def test_shares_page_opened(self): shares_page = self.home_pg.go_to_project_share_sharespage() self.assertEqual(shares_page.page_title, 'Shares - OpenStack Dashboard') def test_share_snapshots_page_opened(self): s_snaps_page = self.home_pg.go_to_project_share_sharesnapshotspage() self.assertEqual(s_snaps_page.page_title, 'Share Snapshots - OpenStack Dashboard') def test_share_networks_page_opened(self): s_networks_page = self.home_pg.go_to_project_share_sharenetworkspage() self.assertEqual(s_networks_page.page_title, 'Share Networks - OpenStack Dashboard') def test_security_services_page_opened(self): sec_serv_page = self.home_pg.go_to_project_share_securityservicespage() self.assertEqual(sec_serv_page.page_title, 'Security Services - OpenStack Dashboard') def test_share_groups_page_opened(self): share_groups_page = self.home_pg.go_to_project_share_sharegroupspage() self.assertEqual(share_groups_page.page_title, 'Share Groups - OpenStack Dashboard') def test_share_group_snapthots_page_opened(self): sg_s_page = self.home_pg.go_to_project_share_sharegroupsnapshotspage() self.assertEqual(sg_s_page.page_title, 'Share Group Snapshots - OpenStack Dashboard') class TestManilaAdminDashboardInstalled(helpers.AdminTestCase): def test_shares_page_opened(self): shares_page = self.home_pg.go_to_admin_share_sharespage() self.assertEqual(shares_page.page_title, 'Shares - OpenStack Dashboard') def test_share_snapshots_page_opened(self): s_snapshots_page = self.home_pg.go_to_admin_share_sharesnapshotspage() # TODO(e0ne): fix page title and test self.assertEqual(s_snapshots_page.page_title, 'Shares - OpenStack Dashboard') def test_share_snapshot_types_page_opened(self): share_types_page = ( self.home_pg.go_to_admin_share_sharetypespage()) self.assertEqual(share_types_page.page_title, 'Share Types - OpenStack Dashboard') def test_share_networks_page_opened(self): s_networks_page = self.home_pg.go_to_admin_share_sharenetworkspage() self.assertEqual(s_networks_page.page_title, 'Share Networks - OpenStack Dashboard') def test_security_services_page_opened(self): sec_serv_page = self.home_pg.go_to_admin_share_securityservicespage() self.assertEqual(sec_serv_page.page_title, 'Security Services - OpenStack Dashboard') def test_share_servers_page_opened(self): share_serv_page = self.home_pg.go_to_admin_share_shareserverspage() self.assertEqual(share_serv_page.page_title, 'Share Servers - OpenStack Dashboard') def test_share_instences_page_opened(self): sec_serv_page = self.home_pg.go_to_admin_share_shareinstancespage() self.assertEqual(sec_serv_page.page_title, 'Share Instances - OpenStack Dashboard') def test_share_groups_page_opened(self): share_groups_page = self.home_pg.go_to_admin_share_sharegroupspage() self.assertEqual(share_groups_page.page_title, 'Share Groups - OpenStack Dashboard') def test_share_group_snapthots_page_opened(self): sg_s_page = self.home_pg.go_to_admin_share_sharegroupsnapshotspage() self.assertEqual(sg_s_page.page_title, 'Share Group Snapshots - OpenStack Dashboard') def test_share_group_types_page_opened(self): sg_types_page = self.home_pg.go_to_admin_share_sharegrouptypespage() self.assertEqual(sg_types_page.page_title, 'Share Group Types - OpenStack Dashboard') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/settings.py0000664000175000017500000000203000000000000020775 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from horizon.test.settings import * # noqa from openstack_dashboard.test.settings import * # noqa # Load the pluggable dashboard settings import manila_ui.local.enabled import openstack_dashboard.enabled from openstack_dashboard.utils import settings MANILA_UI_APPS = list(INSTALLED_APPS) + ['manila_ui.dashboards'] settings.update_dashboards( [ manila_ui.local.enabled, openstack_dashboard.enabled, ], HORIZON_CONFIG, MANILA_UI_APPS, ) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8466513 manila-ui-11.0.0/manila_ui/tests/test_data/0000775000175000017500000000000000000000000020540 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/test_data/__init__.py0000664000175000017500000000000000000000000022637 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/test_data/keystone_data.py0000664000175000017500000000222300000000000023743 0ustar00zuulzuul00000000000000# 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. def data(TEST): # Add manila to the keystone data TEST.service_catalog.append( {"type": "share", "name": "Manila", "endpoints_links": [], "endpoints": [ {"region": "RegionOne", "adminURL": "http://admin.manila.example.com:8786/v1", "internalURL": "http://int.manila.example.com:8786/v1", "publicURL": "http://public.manila.example.com:8786/v1"}]}, ) projects = [ type("%sProject" % v, (object, ), {'id': '%s_id' % v, 'name': '%s_name' % v}) for v in ('foo', 'bar', 'quuz') ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/test_data/utils.py0000664000175000017500000000227100000000000022254 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from openstack_dashboard.test.test_data import utils def load_test_data(load_onto=None): from manila_ui.tests.test_data import keystone_data as manila_keystone_data from openstack_dashboard.test.test_data import exceptions from openstack_dashboard.test.test_data import keystone_data # The order of these loaders matters, some depend on others. loaders = ( exceptions.data, keystone_data.data, manila_keystone_data.data, ) if load_onto: for data_func in loaders: data_func(load_onto) return load_onto else: return utils.TestData(*loaders) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/urls.py0000664000175000017500000000134600000000000020133 0ustar00zuulzuul00000000000000# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from django.urls import include from django.urls import re_path import openstack_dashboard.urls urlpatterns = [ re_path(r'', include(openstack_dashboard.urls)) ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8466513 manila-ui-11.0.0/manila_ui/tests/utils/0000775000175000017500000000000000000000000017730 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/utils/__init__.py0000664000175000017500000000000000000000000022027 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/tests/utils/tests.py0000664000175000017500000000267500000000000021456 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from manila_ui.dashboards.utils import transform_dashed_name as tdn from manila_ui.tests import helpers as test class UtilsTests(test.TestCase): def test_no_transform(self): inputs = ['foo', 'bar01', 'baz_01'] res = [tdn(x) for x in inputs] self.assertEqual(inputs, res) def test_transform(self): inputs = ['Foo', 'Bar01', 'baz-01'] exp_res = ['izxw6___', 'ijqxembr', 'mjqxuljqge______'] res = [tdn(x) for x in inputs] self.assertEqual(res, exp_res) def test_undo_transform(self): inputs = ['izxw6___', 'ijqxembr', 'mjqxuljqge______'] exp_res = ['Foo', 'Bar01', 'baz-01'] res = [tdn(x) for x in inputs] self.assertEqual(res, exp_res) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8466513 manila-ui-11.0.0/manila_ui/utils/0000775000175000017500000000000000000000000016566 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/manila_ui/utils/__init__.py0000664000175000017500000000000000000000000020665 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7906513 manila-ui-11.0.0/manila_ui.egg-info/0000775000175000017500000000000000000000000017120 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/PKG-INFO0000664000175000017500000000343700000000000020224 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: manila-ui Version: 11.0.0 Summary: Manila Management Dashboard Home-page: https://docs.openstack.org/manila-ui/latest/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: Team and repository tags ------------------------ .. image:: https://governance.openstack.org/tc/badges/manila-ui.svg :target: https://governance.openstack.org/tc/reference/tags/index.html .. Change things from this point on ======================================= manila-ui - Manila Management Dashboard ======================================= * Free software: Apache license * Documentation: https://docs.openstack.org/manila-ui/latest/ * Release notes: https://docs.openstack.org/releasenotes/manila-ui/ * Source: https://opendev.org/openstack/manila-ui * Bugs: https://bugs.launchpad.net/manila-ui Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Requires-Python: >=3.6 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/SOURCES.txt0000664000175000017500000007503600000000000021017 0ustar00zuulzuul00000000000000.coveragerc .mailmap .testr.conf .zuul.yaml AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE README.rst babel-django.cfg babel-djangojs.cfg bindep.txt manage.py requirements.txt run_tests.sh setup.cfg setup.py test-requirements.txt tox.ini devstack/plugin.sh devstack/settings doc/requirements.txt doc/source/conf.py doc/source/index.rst doc/source/admin/index.rst doc/source/configuration/index.rst doc/source/contributor/adding_release_notes.rst doc/source/contributor/contributing.rst doc/source/contributor/development-environment.rst doc/source/contributor/features.rst doc/source/contributor/index.rst doc/source/install/installation.rst doc/source/user/index.rst manila_ui/__init__.py manila_ui/exceptions.py manila_ui/features.py manila_ui.egg-info/PKG-INFO manila_ui.egg-info/SOURCES.txt manila_ui.egg-info/dependency_links.txt manila_ui.egg-info/not-zip-safe manila_ui.egg-info/pbr.json manila_ui.egg-info/requires.txt manila_ui.egg-info/top_level.txt manila_ui/api/__init__.py manila_ui/api/manila.py manila_ui/conf/manila_policy.yaml manila_ui/conf/default_policies/manila.yaml manila_ui/dashboards/__init__.py manila_ui/dashboards/utils.py manila_ui/dashboards/admin/__init__.py manila_ui/dashboards/admin/utils.py manila_ui/dashboards/admin/defaults/__init__.py manila_ui/dashboards/admin/defaults/tables.py manila_ui/dashboards/admin/defaults/tabs.py manila_ui/dashboards/admin/defaults/workflows.py manila_ui/dashboards/admin/security_services/__init__.py manila_ui/dashboards/admin/security_services/panel.py manila_ui/dashboards/admin/security_services/tables.py manila_ui/dashboards/admin/security_services/tabs.py manila_ui/dashboards/admin/security_services/urls.py manila_ui/dashboards/admin/security_services/views.py manila_ui/dashboards/admin/security_services/templates/security_services/_detail.html manila_ui/dashboards/admin/security_services/templates/security_services/detail.html manila_ui/dashboards/admin/security_services/templates/security_services/index.html manila_ui/dashboards/admin/share_group_snapshots/__init__.py manila_ui/dashboards/admin/share_group_snapshots/forms.py manila_ui/dashboards/admin/share_group_snapshots/panel.py manila_ui/dashboards/admin/share_group_snapshots/tables.py manila_ui/dashboards/admin/share_group_snapshots/tabs.py manila_ui/dashboards/admin/share_group_snapshots/urls.py manila_ui/dashboards/admin/share_group_snapshots/views.py manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/_detail.html manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/_reset_status.html manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/detail.html manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/index.html manila_ui/dashboards/admin/share_group_snapshots/templates/share_group_snapshots/reset_status.html manila_ui/dashboards/admin/share_group_types/__init__.py manila_ui/dashboards/admin/share_group_types/forms.py manila_ui/dashboards/admin/share_group_types/panel.py manila_ui/dashboards/admin/share_group_types/tables.py manila_ui/dashboards/admin/share_group_types/urls.py manila_ui/dashboards/admin/share_group_types/views.py manila_ui/dashboards/admin/share_group_types/workflows.py manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_create.html manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_manage_access.html manila_ui/dashboards/admin/share_group_types/templates/share_group_types/_update.html manila_ui/dashboards/admin/share_group_types/templates/share_group_types/create.html manila_ui/dashboards/admin/share_group_types/templates/share_group_types/index.html manila_ui/dashboards/admin/share_group_types/templates/share_group_types/manage_access.html manila_ui/dashboards/admin/share_group_types/templates/share_group_types/update.html manila_ui/dashboards/admin/share_groups/__init__.py manila_ui/dashboards/admin/share_groups/forms.py manila_ui/dashboards/admin/share_groups/panel.py manila_ui/dashboards/admin/share_groups/tables.py manila_ui/dashboards/admin/share_groups/tabs.py manila_ui/dashboards/admin/share_groups/urls.py manila_ui/dashboards/admin/share_groups/views.py manila_ui/dashboards/admin/share_groups/templates/share_groups/_detail.html manila_ui/dashboards/admin/share_groups/templates/share_groups/_reset_status.html manila_ui/dashboards/admin/share_groups/templates/share_groups/detail.html manila_ui/dashboards/admin/share_groups/templates/share_groups/index.html manila_ui/dashboards/admin/share_groups/templates/share_groups/reset_status.html manila_ui/dashboards/admin/share_instances/__init__.py manila_ui/dashboards/admin/share_instances/panel.py manila_ui/dashboards/admin/share_instances/tables.py manila_ui/dashboards/admin/share_instances/tabs.py manila_ui/dashboards/admin/share_instances/urls.py manila_ui/dashboards/admin/share_instances/views.py manila_ui/dashboards/admin/share_instances/templates/share_instances/_detail.html manila_ui/dashboards/admin/share_instances/templates/share_instances/detail.html manila_ui/dashboards/admin/share_instances/templates/share_instances/index.html manila_ui/dashboards/admin/share_networks/__init__.py manila_ui/dashboards/admin/share_networks/panel.py manila_ui/dashboards/admin/share_networks/tables.py manila_ui/dashboards/admin/share_networks/tabs.py manila_ui/dashboards/admin/share_networks/urls.py manila_ui/dashboards/admin/share_networks/views.py manila_ui/dashboards/admin/share_networks/templates/share_networks/_detail.html manila_ui/dashboards/admin/share_networks/templates/share_networks/detail.html manila_ui/dashboards/admin/share_networks/templates/share_networks/index.html manila_ui/dashboards/admin/share_servers/__init__.py manila_ui/dashboards/admin/share_servers/panel.py manila_ui/dashboards/admin/share_servers/tables.py manila_ui/dashboards/admin/share_servers/tabs.py manila_ui/dashboards/admin/share_servers/urls.py manila_ui/dashboards/admin/share_servers/views.py manila_ui/dashboards/admin/share_servers/templates/share_servers/_detail.html manila_ui/dashboards/admin/share_servers/templates/share_servers/detail.html manila_ui/dashboards/admin/share_servers/templates/share_servers/index.html manila_ui/dashboards/admin/share_snapshots/__init__.py manila_ui/dashboards/admin/share_snapshots/panel.py manila_ui/dashboards/admin/share_snapshots/tables.py manila_ui/dashboards/admin/share_snapshots/tabs.py manila_ui/dashboards/admin/share_snapshots/urls.py manila_ui/dashboards/admin/share_snapshots/views.py manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/_detail.html manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/detail.html manila_ui/dashboards/admin/share_snapshots/templates/share_snapshots/index.html manila_ui/dashboards/admin/share_types/__init__.py manila_ui/dashboards/admin/share_types/forms.py manila_ui/dashboards/admin/share_types/panel.py manila_ui/dashboards/admin/share_types/tables.py manila_ui/dashboards/admin/share_types/urls.py manila_ui/dashboards/admin/share_types/views.py manila_ui/dashboards/admin/share_types/workflows.py manila_ui/dashboards/admin/share_types/templates/share_types/_create.html manila_ui/dashboards/admin/share_types/templates/share_types/_manage_access.html manila_ui/dashboards/admin/share_types/templates/share_types/_update.html manila_ui/dashboards/admin/share_types/templates/share_types/create.html manila_ui/dashboards/admin/share_types/templates/share_types/index.html manila_ui/dashboards/admin/share_types/templates/share_types/manage_access.html manila_ui/dashboards/admin/share_types/templates/share_types/update.html manila_ui/dashboards/admin/shares/__init__.py manila_ui/dashboards/admin/shares/forms.py manila_ui/dashboards/admin/shares/panel.py manila_ui/dashboards/admin/shares/tables.py manila_ui/dashboards/admin/shares/tabs.py manila_ui/dashboards/admin/shares/urls.py manila_ui/dashboards/admin/shares/views.py manila_ui/dashboards/admin/shares/replicas/__init__.py manila_ui/dashboards/admin/shares/replicas/forms.py manila_ui/dashboards/admin/shares/replicas/tables.py manila_ui/dashboards/admin/shares/replicas/tabs.py manila_ui/dashboards/admin/shares/replicas/views.py manila_ui/dashboards/admin/shares/templates/shares/_detail.html manila_ui/dashboards/admin/shares/templates/shares/_manage_share.html manila_ui/dashboards/admin/shares/templates/shares/_migration_cancel.html manila_ui/dashboards/admin/shares/templates/shares/_migration_complete.html manila_ui/dashboards/admin/shares/templates/shares/_migration_get_progress.html manila_ui/dashboards/admin/shares/templates/shares/_migration_start.html manila_ui/dashboards/admin/shares/templates/shares/_unmanage_share.html manila_ui/dashboards/admin/shares/templates/shares/detail.html manila_ui/dashboards/admin/shares/templates/shares/index.html manila_ui/dashboards/admin/shares/templates/shares/manage_share.html manila_ui/dashboards/admin/shares/templates/shares/migration_cancel.html manila_ui/dashboards/admin/shares/templates/shares/migration_complete.html manila_ui/dashboards/admin/shares/templates/shares/migration_get_progress.html manila_ui/dashboards/admin/shares/templates/shares/migration_start.html manila_ui/dashboards/admin/shares/templates/shares/unmanage_share.html manila_ui/dashboards/admin/shares/templates/shares/replicas/_detail_overview.html manila_ui/dashboards/admin/shares/templates/shares/replicas/_reset_replica_state.html manila_ui/dashboards/admin/shares/templates/shares/replicas/_reset_replica_status.html manila_ui/dashboards/admin/shares/templates/shares/replicas/_resync_replica.html manila_ui/dashboards/admin/shares/templates/shares/replicas/detail.html manila_ui/dashboards/admin/shares/templates/shares/replicas/manage_replicas.html manila_ui/dashboards/admin/shares/templates/shares/replicas/reset_replica_state.html manila_ui/dashboards/admin/shares/templates/shares/replicas/reset_replica_status.html manila_ui/dashboards/admin/shares/templates/shares/replicas/resync_replica.html manila_ui/dashboards/admin/user_messages/__init__.py manila_ui/dashboards/admin/user_messages/panel.py manila_ui/dashboards/admin/user_messages/tables.py manila_ui/dashboards/admin/user_messages/tabs.py manila_ui/dashboards/admin/user_messages/urls.py manila_ui/dashboards/admin/user_messages/views.py manila_ui/dashboards/admin/user_messages/templates/user_messages/_detail.html manila_ui/dashboards/admin/user_messages/templates/user_messages/detail.html manila_ui/dashboards/admin/user_messages/templates/user_messages/index.html manila_ui/dashboards/identity/__init__.py manila_ui/dashboards/identity/projects/__init__.py manila_ui/dashboards/identity/projects/workflows.py manila_ui/dashboards/project/__init__.py manila_ui/dashboards/project/config.py manila_ui/dashboards/project/security_services/__init__.py manila_ui/dashboards/project/security_services/forms.py manila_ui/dashboards/project/security_services/panel.py manila_ui/dashboards/project/security_services/tables.py manila_ui/dashboards/project/security_services/tabs.py manila_ui/dashboards/project/security_services/urls.py manila_ui/dashboards/project/security_services/views.py manila_ui/dashboards/project/security_services/templates/security_services/_add.html manila_ui/dashboards/project/security_services/templates/security_services/_create.html manila_ui/dashboards/project/security_services/templates/security_services/_detail.html manila_ui/dashboards/project/security_services/templates/security_services/_update.html manila_ui/dashboards/project/security_services/templates/security_services/add.html manila_ui/dashboards/project/security_services/templates/security_services/create.html manila_ui/dashboards/project/security_services/templates/security_services/detail.html manila_ui/dashboards/project/security_services/templates/security_services/index.html manila_ui/dashboards/project/security_services/templates/security_services/update.html manila_ui/dashboards/project/share_group_snapshots/__init__.py manila_ui/dashboards/project/share_group_snapshots/forms.py manila_ui/dashboards/project/share_group_snapshots/panel.py manila_ui/dashboards/project/share_group_snapshots/tables.py manila_ui/dashboards/project/share_group_snapshots/tabs.py manila_ui/dashboards/project/share_group_snapshots/urls.py manila_ui/dashboards/project/share_group_snapshots/views.py manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/_create.html manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/_detail.html manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/_update.html manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/create.html manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/detail.html manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/index.html manila_ui/dashboards/project/share_group_snapshots/templates/share_group_snapshots/update.html manila_ui/dashboards/project/share_groups/__init__.py manila_ui/dashboards/project/share_groups/forms.py manila_ui/dashboards/project/share_groups/panel.py manila_ui/dashboards/project/share_groups/tables.py manila_ui/dashboards/project/share_groups/tabs.py manila_ui/dashboards/project/share_groups/urls.py manila_ui/dashboards/project/share_groups/views.py manila_ui/dashboards/project/share_groups/templates/share_groups/_create.html manila_ui/dashboards/project/share_groups/templates/share_groups/_detail.html manila_ui/dashboards/project/share_groups/templates/share_groups/_update.html manila_ui/dashboards/project/share_groups/templates/share_groups/create.html manila_ui/dashboards/project/share_groups/templates/share_groups/detail.html manila_ui/dashboards/project/share_groups/templates/share_groups/index.html manila_ui/dashboards/project/share_groups/templates/share_groups/update.html manila_ui/dashboards/project/share_networks/__init__.py manila_ui/dashboards/project/share_networks/forms.py manila_ui/dashboards/project/share_networks/panel.py manila_ui/dashboards/project/share_networks/tables.py manila_ui/dashboards/project/share_networks/tabs.py manila_ui/dashboards/project/share_networks/urls.py manila_ui/dashboards/project/share_networks/views.py manila_ui/dashboards/project/share_networks/workflows.py manila_ui/dashboards/project/share_networks/templates/share_networks/_create.html manila_ui/dashboards/project/share_networks/templates/share_networks/_detail.html manila_ui/dashboards/project/share_networks/templates/share_networks/_update.html manila_ui/dashboards/project/share_networks/templates/share_networks/create.html manila_ui/dashboards/project/share_networks/templates/share_networks/detail.html manila_ui/dashboards/project/share_networks/templates/share_networks/index.html manila_ui/dashboards/project/share_networks/templates/share_networks/update.html manila_ui/dashboards/project/share_snapshots/__init__.py manila_ui/dashboards/project/share_snapshots/forms.py manila_ui/dashboards/project/share_snapshots/panel.py manila_ui/dashboards/project/share_snapshots/tables.py manila_ui/dashboards/project/share_snapshots/tabs.py manila_ui/dashboards/project/share_snapshots/urls.py manila_ui/dashboards/project/share_snapshots/views.py manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_create.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_detail.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_limits.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_rule_add.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/_update.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/create.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/detail.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/index.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/manage_rules.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/rule_add.html manila_ui/dashboards/project/share_snapshots/templates/share_snapshots/update.html manila_ui/dashboards/project/shares/__init__.py manila_ui/dashboards/project/shares/forms.py manila_ui/dashboards/project/shares/panel.py manila_ui/dashboards/project/shares/tables.py manila_ui/dashboards/project/shares/tabs.py manila_ui/dashboards/project/shares/urls.py manila_ui/dashboards/project/shares/views.py manila_ui/dashboards/project/shares/replicas/__init__.py manila_ui/dashboards/project/shares/replicas/forms.py manila_ui/dashboards/project/shares/replicas/tables.py manila_ui/dashboards/project/shares/replicas/tabs.py manila_ui/dashboards/project/shares/replicas/views.py manila_ui/dashboards/project/shares/templates/shares/_create.html manila_ui/dashboards/project/shares/templates/shares/_detail.html manila_ui/dashboards/project/shares/templates/shares/_limits.html manila_ui/dashboards/project/shares/templates/shares/_manage_rules.html manila_ui/dashboards/project/shares/templates/shares/_resize.html manila_ui/dashboards/project/shares/templates/shares/_resize_limits.html manila_ui/dashboards/project/shares/templates/shares/_revert.html manila_ui/dashboards/project/shares/templates/shares/_rule_add.html manila_ui/dashboards/project/shares/templates/shares/_update.html manila_ui/dashboards/project/shares/templates/shares/_update_metadata.html manila_ui/dashboards/project/shares/templates/shares/_update_rule_metadata.html manila_ui/dashboards/project/shares/templates/shares/create.html manila_ui/dashboards/project/shares/templates/shares/detail.html manila_ui/dashboards/project/shares/templates/shares/index.html manila_ui/dashboards/project/shares/templates/shares/manage_rules.html manila_ui/dashboards/project/shares/templates/shares/resize.html manila_ui/dashboards/project/shares/templates/shares/revert.html manila_ui/dashboards/project/shares/templates/shares/rule_add.html manila_ui/dashboards/project/shares/templates/shares/update.html manila_ui/dashboards/project/shares/templates/shares/update_metadata.html manila_ui/dashboards/project/shares/templates/shares/update_rule_metadata.html manila_ui/dashboards/project/shares/templates/shares/replicas/_create_replica.html manila_ui/dashboards/project/shares/templates/shares/replicas/_detail_overview.html manila_ui/dashboards/project/shares/templates/shares/replicas/_set_replica_as_active.html manila_ui/dashboards/project/shares/templates/shares/replicas/create_replica.html manila_ui/dashboards/project/shares/templates/shares/replicas/detail.html manila_ui/dashboards/project/shares/templates/shares/replicas/manage_replicas.html manila_ui/dashboards/project/shares/templates/shares/replicas/set_replica_as_active.html manila_ui/dashboards/project/user_messages/__init__.py manila_ui/dashboards/project/user_messages/panel.py manila_ui/dashboards/project/user_messages/tables.py manila_ui/dashboards/project/user_messages/tabs.py manila_ui/dashboards/project/user_messages/urls.py manila_ui/dashboards/project/user_messages/views.py manila_ui/dashboards/project/user_messages/templates/user_messages/_detail.html manila_ui/dashboards/project/user_messages/templates/user_messages/detail.html manila_ui/dashboards/project/user_messages/templates/user_messages/index.html manila_ui/local/__init__.py manila_ui/local/enabled/_80_manila_admin_add_share_panel_group.py manila_ui/local/enabled/_80_manila_project_add_share_panel_group.py manila_ui/local/enabled/_9010_manila_admin_add_shares_panel_to_share_panel_group.py manila_ui/local/enabled/_9010_manila_project_add_shares_panel_to_share_panel_group.py manila_ui/local/enabled/_9020_manila_admin_add_share_snapshots_panel_to_share_panel_group.py manila_ui/local/enabled/_9020_manila_project_add_share_snapshots_panel_to_share_panel_group.py manila_ui/local/enabled/_9030_manila_admin_add_share_types_panel_to_share_panel_group.py manila_ui/local/enabled/_9040_manila_admin_add_share_networks_panel_to_share_panel_group.py manila_ui/local/enabled/_9040_manila_project_add_share_networks_panel_to_share_panel_group.py manila_ui/local/enabled/_9050_manila_admin_add_security_services_panel_to_share_panel_group.py manila_ui/local/enabled/_9050_manila_project_add_security_services_panel_to_share_panel_group.py manila_ui/local/enabled/_9060_manila_admin_add_share_servers_panel_to_share_panel_group.py manila_ui/local/enabled/_9070_manila_admin_add_share_instances_panel_to_share_panel_group.py manila_ui/local/enabled/_9080_manila_admin_add_share_groups_panel_to_share_panel_group.py manila_ui/local/enabled/_9080_manila_project_add_share_groups_panel_to_share_panel_group.py manila_ui/local/enabled/_9085_manila_admin_add_share_group_snapshots_panel_to_share_panel_group.py manila_ui/local/enabled/_9085_manila_project_add_share_group_snapshots_panel_to_share_panel_group.py manila_ui/local/enabled/_9090_manila_admin_add_share_group_types_panel_to_share_panel_group.py manila_ui/local/enabled/_9095_manila_admin_add_user_messages_panel_to_share_panel_group.py manila_ui/local/enabled/_9095_manila_project_add_user_messages_panel_to_share_panel_group.py manila_ui/local/enabled/__init__.py manila_ui/local/local_settings.d/_90_manila_shares.py manila_ui/locale/cs/LC_MESSAGES/django.po manila_ui/locale/de/LC_MESSAGES/django.po manila_ui/locale/en_GB/LC_MESSAGES/django.po manila_ui/locale/fr/LC_MESSAGES/django.po manila_ui/locale/id/LC_MESSAGES/django.po manila_ui/locale/ko_KR/LC_MESSAGES/django.po manila_ui/locale/pt_BR/LC_MESSAGES/django.po manila_ui/locale/ru/LC_MESSAGES/django.po manila_ui/locale/tr_TR/LC_MESSAGES/django.po manila_ui/tests/__init__.py manila_ui/tests/helpers.py manila_ui/tests/settings.py manila_ui/tests/urls.py manila_ui/tests/api/__init__.py manila_ui/tests/api/test_manila.py manila_ui/tests/dashboards/__init__.py manila_ui/tests/dashboards/test_utils.py manila_ui/tests/dashboards/admin/__init__.py manila_ui/tests/dashboards/admin/security_services/__init__.py manila_ui/tests/dashboards/admin/security_services/tests.py manila_ui/tests/dashboards/admin/share_group_snapshots/__init__.py manila_ui/tests/dashboards/admin/share_group_snapshots/tests.py manila_ui/tests/dashboards/admin/share_group_types/__init__.py manila_ui/tests/dashboards/admin/share_group_types/tests.py manila_ui/tests/dashboards/admin/share_groups/__init__.py manila_ui/tests/dashboards/admin/share_groups/tests.py manila_ui/tests/dashboards/admin/share_instances/__init__.py manila_ui/tests/dashboards/admin/share_instances/tests.py manila_ui/tests/dashboards/admin/share_networks/__init__.py manila_ui/tests/dashboards/admin/share_networks/tests.py manila_ui/tests/dashboards/admin/share_servers/__init__.py manila_ui/tests/dashboards/admin/share_servers/tests.py manila_ui/tests/dashboards/admin/share_snapshots/__init__.py manila_ui/tests/dashboards/admin/share_snapshots/tests.py manila_ui/tests/dashboards/admin/share_types/__init__.py manila_ui/tests/dashboards/admin/share_types/test_forms.py manila_ui/tests/dashboards/admin/share_types/tests.py manila_ui/tests/dashboards/admin/shares/__init__.py manila_ui/tests/dashboards/admin/shares/test_forms.py manila_ui/tests/dashboards/admin/shares/tests.py manila_ui/tests/dashboards/admin/shares/replicas/__init__.py manila_ui/tests/dashboards/admin/shares/replicas/tests.py manila_ui/tests/dashboards/admin/user_messages/__init__.py manila_ui/tests/dashboards/admin/user_messages/tests.py manila_ui/tests/dashboards/identity/__init__.py manila_ui/tests/dashboards/identity/projects/__init__.py manila_ui/tests/dashboards/identity/projects/tests.py manila_ui/tests/dashboards/project/__init__.py manila_ui/tests/dashboards/project/test_data.py manila_ui/tests/dashboards/project/tests.py manila_ui/tests/dashboards/project/security_services/__init__.py manila_ui/tests/dashboards/project/security_services/tests.py manila_ui/tests/dashboards/project/share_group_snapshots/__init__.py manila_ui/tests/dashboards/project/share_group_snapshots/tests.py manila_ui/tests/dashboards/project/share_groups/__init__.py manila_ui/tests/dashboards/project/share_groups/tests.py manila_ui/tests/dashboards/project/share_networks/__init__.py manila_ui/tests/dashboards/project/share_networks/tests.py manila_ui/tests/dashboards/project/share_snapshots/__init__.py manila_ui/tests/dashboards/project/share_snapshots/test_tables.py manila_ui/tests/dashboards/project/share_snapshots/tests.py manila_ui/tests/dashboards/project/shares/__init__.py manila_ui/tests/dashboards/project/shares/tests.py manila_ui/tests/dashboards/project/shares/replicas/__init__.py manila_ui/tests/dashboards/project/shares/replicas/tests.py manila_ui/tests/dashboards/project/user_messages/__init__.py manila_ui/tests/dashboards/project/user_messages/tests.py manila_ui/tests/integration/__init__.py manila_ui/tests/integration/horizon.conf manila_ui/tests/integration/test_basic.py manila_ui/tests/integration/pages/__init__.py manila_ui/tests/integration/pages/admin/__init__.py manila_ui/tests/integration/pages/admin/share/__init__.py manila_ui/tests/integration/pages/admin/share/messagespage.py manila_ui/tests/integration/pages/admin/share/securityservicespage.py manila_ui/tests/integration/pages/admin/share/sharegroupsnapshotspage.py manila_ui/tests/integration/pages/admin/share/sharegroupspage.py manila_ui/tests/integration/pages/admin/share/sharegroupssnapshotspage.py manila_ui/tests/integration/pages/admin/share/sharegrouptypespage.py manila_ui/tests/integration/pages/admin/share/shareinstancespage.py manila_ui/tests/integration/pages/admin/share/sharenetworkspage.py manila_ui/tests/integration/pages/admin/share/shareserverspage.py manila_ui/tests/integration/pages/admin/share/sharesnapshotspage.py manila_ui/tests/integration/pages/admin/share/sharespage.py manila_ui/tests/integration/pages/admin/share/sharetypespage.py manila_ui/tests/integration/pages/project/__init__.py manila_ui/tests/integration/pages/project/share/__init__.py manila_ui/tests/integration/pages/project/share/messagespage.py manila_ui/tests/integration/pages/project/share/securityservicespage.py manila_ui/tests/integration/pages/project/share/sharegroupsnapshotspage.py manila_ui/tests/integration/pages/project/share/sharegroupspage.py manila_ui/tests/integration/pages/project/share/sharenetworkspage.py manila_ui/tests/integration/pages/project/share/sharesnapshotspage.py manila_ui/tests/integration/pages/project/share/sharespage.py manila_ui/tests/test_data/__init__.py manila_ui/tests/test_data/keystone_data.py manila_ui/tests/test_data/utils.py manila_ui/tests/utils/__init__.py manila_ui/tests/utils/tests.py manila_ui/utils/__init__.py releasenotes/notes/.placeholder releasenotes/notes/add-create-share-type-with-description-d57f4c734d107554.yaml releasenotes/notes/add-is-default-field-to-share-group-types-list-e0ed183e2e8df9ea.yaml releasenotes/notes/add-is-default-field-to-share-types-list-a76fed8ebe7eef03.yaml releasenotes/notes/add-maprfs-protocol-5d7f4b4c47da8fab.yaml releasenotes/notes/add-revert-share-to-snapshot-support-cba6227cef75c1a7.yaml releasenotes/notes/add-share-access-rules-66a86a45a1f4a9c8.yaml releasenotes/notes/add-share-panel-group-to-admin-dashboard-ef6a02243c0e776c.yaml releasenotes/notes/add-share-panel-group-to-project-dashboard-722ab48392588728.yaml releasenotes/notes/add-support-for-microversion-2-34-share-groups-fields-f447cd6563e377c1.yaml releasenotes/notes/allow-access-to-ipv6-clients-2.38-154d308ec87bfb73.yaml releasenotes/notes/bp-manila-mountable-snapshots-93a732ad0dc95ade.yaml releasenotes/notes/bp-ocata-migration-improvements-e0ecccbe95e3c265.yaml releasenotes/notes/bp-share-network-subnets-82ad8c601caf177b.yaml releasenotes/notes/bp-ui-user-messages-6ff935cabc516be0.yaml releasenotes/notes/bp-update-share-type-name-or-description-cc5357feee2a3b61.yaml releasenotes/notes/bug-1498433-42796ef1e266f4d3.yaml releasenotes/notes/bug-1619244-1cc15914050d9a64.yaml releasenotes/notes/bug-1664370-drop-host-field-in-project-view-tables-20b7a67023d57d35.yaml releasenotes/notes/bug-1679960-fix-quota-names-overlapping-4277d45cd0110489.yaml releasenotes/notes/bug-1685655-drop-snapshot-support-param-a4e7c7ee068c8bc9.yaml releasenotes/notes/bug-1685657-fix-create-share-from-snapshot-form-7f5993c1100ce9b6.yaml releasenotes/notes/bug-1702396-add-share-servers-to-share-network-details-1cff66010817f1a8.yaml releasenotes/notes/bug-1702396-fix-cannot-get-share-network-details-83e2882df1714506.yaml releasenotes/notes/bug-1783232-fix-quotas-retrieval-for-shares-and-snapshots-tables-63a1fc877029eac8.yaml releasenotes/notes/bug-1787016-fix-share-replica-details-eecdc8b43f2a6008.yaml releasenotes/notes/bug-1823078-upgrade-api-to-v2.33-82871432659a8285.yaml releasenotes/notes/bug-1842119-fix-get-quotas-for-update-quotas-share-7f229e4e011004cd.yaml releasenotes/notes/bug-1931641-fix-handling-share-type-name-with-hyphens-8a9f16af36da5852.yaml releasenotes/notes/bug-1967312-fix-shares-panel-8b5da4eee68ba6c4.yaml releasenotes/notes/bug-1968925-fix-replica-creation-190321bf9fefe179.yaml releasenotes/notes/bug-2004165-fix-type-listing-when-rbac-enabled-c01f363dfa574b9b.yaml releasenotes/notes/bug-2043572-fix-error-in-share-creation-1a8feef763c21b25.yaml releasenotes/notes/bug-873434-fix-set-as-active-button-visibility-e7cc416d66ab360b.yaml releasenotes/notes/drop-python2-support-8f7cbc2c3a758777.yaml releasenotes/notes/field-encoder-update-7141766f0b5f8ecb.yaml releasenotes/notes/filter-share-type-by-extra-spec-2.43-39710ce64f8be239.yaml releasenotes/notes/policy-in-code-support-23744e26a7f6e284.yaml releasenotes/notes/python-manilaclient-yoga-ef2c44b205fa216b.yaml releasenotes/notes/raise-python-manilaclient-version-9caa15ec2c94968d.yaml releasenotes/notes/remove-nova-net-plugin-4fdc0d944d93644f.yaml releasenotes/notes/security-service-ou-field-2.44-c288a880b9b0fa68.yaml releasenotes/notes/share-shrinking-c1d46fc1c3ce29b7.yaml releasenotes/notes/start-using-reno-49da440f5e237dda.yaml releasenotes/source/2023.1.rst releasenotes/source/2023.2.rst releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/newton.rst releasenotes/source/ocata.rst releasenotes/source/pike.rst releasenotes/source/queens.rst releasenotes/source/rocky.rst releasenotes/source/stein.rst releasenotes/source/train.rst releasenotes/source/unreleased.rst releasenotes/source/ussuri.rst releasenotes/source/victoria.rst releasenotes/source/wallaby.rst releasenotes/source/xena.rst releasenotes/source/yoga.rst releasenotes/source/zed.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder releasenotes/source/locale/de/LC_MESSAGES/releasenotes.po releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po releasenotes/source/locale/id/LC_MESSAGES/releasenotes.po releasenotes/source/locale/ja/LC_MESSAGES/releasenotes.po releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po releasenotes/source/locale/pt_BR/LC_MESSAGES/releasenotes.po releasenotes/source/locale/zh_CN/LC_MESSAGES/releasenotes.po tools/cover.sh tools/with_venv.sh././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/dependency_links.txt0000664000175000017500000000000100000000000023166 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/not-zip-safe0000664000175000017500000000000100000000000021346 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/pbr.json0000664000175000017500000000005600000000000020577 0ustar00zuulzuul00000000000000{"git_version": "04861a8", "is_release": true}././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/requires.txt0000664000175000017500000000021400000000000021515 0ustar00zuulzuul00000000000000django-compressor>=2.0 horizon>=18.3.1 iso8601>=0.1.12 oslo.utils>=4.7.0 pbr>=5.5.0 python-keystoneclient>=4.1.1 python-manilaclient>=2.7.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145162.0 manila-ui-11.0.0/manila_ui.egg-info/top_level.txt0000664000175000017500000000001200000000000021643 0ustar00zuulzuul00000000000000manila_ui ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/0000775000175000017500000000000000000000000016161 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8506515 manila-ui-11.0.0/releasenotes/notes/0000775000175000017500000000000000000000000017311 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/.placeholder0000664000175000017500000000000000000000000021562 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-create-share-type-with-description-d57f4c734d107554.yaml0000664000175000017500000000011300000000000031614 0ustar00zuulzuul00000000000000--- features: - Added possibility to create share type with description. ././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=manila-ui-11.0.0/releasenotes/notes/add-is-default-field-to-share-group-types-list-e0ed183e2e8df9ea.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-is-default-field-to-share-group-types-list-e0ed183e2e8df9ea.0000664000175000017500000000025600000000000032612 0ustar00zuulzuul00000000000000--- features: - | Adds ‘is_default’ field to share group types list. the Is_default Column will show 'Yes' if the share group type is default share group type. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-is-default-field-to-share-types-list-a76fed8ebe7eef03.yaml0000664000175000017500000000023500000000000032424 0ustar00zuulzuul00000000000000--- features: - | Added ‘is_default’ field to share types list. the Is_default Column will show 'Yes' if the share type is default share type. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-maprfs-protocol-5d7f4b4c47da8fab.yaml0000664000175000017500000000010700000000000026511 0ustar00zuulzuul00000000000000--- features: - Added native protocol for MapRFS manila share driver ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-revert-share-to-snapshot-support-cba6227cef75c1a7.yaml0000664000175000017500000000011400000000000031667 0ustar00zuulzuul00000000000000--- features: - Added possibility to revert share to its latest snapshot. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-share-access-rules-66a86a45a1f4a9c8.yaml0000664000175000017500000000017000000000000026635 0ustar00zuulzuul00000000000000--- features: - | Added access metadata for share access and also introduced the GET /share-access-rules API. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-share-panel-group-to-admin-dashboard-ef6a02243c0e776c.yaml0000664000175000017500000000106300000000000032120 0ustar00zuulzuul00000000000000--- features: - Admin dashboard now has manila-specific panel group called 'share'. All 'tabs' we had before are panels in this group now. Each panel is loaded in separate page. It allows us to avoid making redundant API calls that we did loading all tabs at once. upgrade: - URLs for resources in admin dashboard were changed. One part of changes is removal of intermediate "shares" part. Example - was - "/admin/shares/share_networks/" became - "/admin/share_networks/" Other part is rename of resource actions to be more alike. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-share-panel-group-to-project-dashboard-722ab48392588728.yaml0000664000175000017500000000107300000000000032221 0ustar00zuulzuul00000000000000--- features: - Project dashboard now has manila-specific panel group called 'share'. All 'tabs' we had before are panels in this group now. Each panel is loaded in separate page. It allows us to avoid making redundant API calls that we did loading all tabs at once. upgrade: - URLs for resources in project dashboard were changed. One part of changes is removal of intermediate "shares" part. Example - was - "/project/shares/share_networks/" became - "/project/share_networks/" Other part is rename of resource actions to be more alike. ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/releasenotes/notes/add-support-for-microversion-2-34-share-groups-fields-f447cd6563e377c1.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/add-support-for-microversion-2-34-share-groups-fields-f447cd65630000664000175000017500000000023200000000000032555 0ustar00zuulzuul00000000000000--- features: - | The share groups dashboards now show the share group availability zone, share group type details and share group capabilities.././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/allow-access-to-ipv6-clients-2.38-154d308ec87bfb73.yaml0000664000175000017500000000010600000000000030321 0ustar00zuulzuul00000000000000--- features: - | IPv6 access rules can now be added to shares. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bp-manila-mountable-snapshots-93a732ad0dc95ade.yaml0000664000175000017500000000012300000000000030407 0ustar00zuulzuul00000000000000--- features: - Added support for the mountable snapshots feature to manila-ui. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bp-ocata-migration-improvements-e0ecccbe95e3c265.yaml0000664000175000017500000000020600000000000031033 0ustar00zuulzuul00000000000000--- features: - Added preserve-snapshots option to share migration. fixes: - Updated descriptions of share migration parameters. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bp-share-network-subnets-82ad8c601caf177b.yaml0000664000175000017500000000042300000000000027336 0ustar00zuulzuul00000000000000--- features: - | Switched share network creation to a two-step workflow. We now allow configuring an availability zone with the initial network subnet associated with the share network. Share network detail panels have been updated accordingly as well ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bp-ui-user-messages-6ff935cabc516be0.yaml0000664000175000017500000000033300000000000026345 0ustar00zuulzuul00000000000000--- features: - | Implements the user messages graphical interface for the project and admin dashboards. [`blueprint ui-user-messages `_] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bp-update-share-type-name-or-description-cc5357feee2a3b61.yaml0000664000175000017500000000026400000000000032367 0ustar00zuulzuul00000000000000--- features: - | The ``name``, ``description`` and/or ``share_type_access:is_public`` attributes of share types can be updated with API version ``2.50`` and beyond. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1498433-42796ef1e266f4d3.yaml0000664000175000017500000000022000000000000023752 0ustar00zuulzuul00000000000000--- fixes: - Availability zone field is now shown for both public and private shares in the dashboard showing detailed share information. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1619244-1cc15914050d9a64.yaml0000664000175000017500000000007200000000000023646 0ustar00zuulzuul00000000000000--- fixes: - Fixed Manage Replicas button availability. ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=manila-ui-11.0.0/releasenotes/notes/bug-1664370-drop-host-field-in-project-view-tables-20b7a67023d57d35.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1664370-drop-host-field-in-project-view-tables-20b7a67023d570000664000175000017500000000042200000000000031660 0ustar00zuulzuul00000000000000--- fixes: - | Drop the ``host`` field from project view tables since this information is only visible to administrators. This is the UI side of `Launchpad bug 1664370 `_ and completes the fix for that bug. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1679960-fix-quota-names-overlapping-4277d45cd0110489.yaml0000664000175000017500000000023200000000000031146 0ustar00zuulzuul00000000000000--- fixes: - Fixed quota names overlapping with Cinder's quotas. Now it is possible to read/write any manila quotas not messing up Cinder's quotas. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1685655-drop-snapshot-support-param-a4e7c7ee068c8bc9.yaml0000664000175000017500000000054600000000000031620 0ustar00zuulzuul00000000000000--- fixes: - | "snapshot_support" is no longer automatically included as an extra-spec in share types created via manila-ui. If the share type has to match backends that support snapshots, explicitly specify "snapshot_support" in the "Extra specs" field while creating share types. This change does not modify pre-existing share types. ././@PaxHeader0000000000000000000000000000021100000000000011447 xustar0000000000000000115 path=manila-ui-11.0.0/releasenotes/notes/bug-1685657-fix-create-share-from-snapshot-form-7f5993c1100ce9b6.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1685657-fix-create-share-from-snapshot-form-7f5993c1100ce9b60000664000175000017500000000031000000000000031674 0ustar00zuulzuul00000000000000--- fixes: - Fixed form of share creation from snapshot. Before it was losing source snapshot ID in request and was creating share from scratch instead of expected snapshot-sourced variant. ././@PaxHeader0000000000000000000000000000022000000000000011447 xustar0000000000000000122 path=manila-ui-11.0.0/releasenotes/notes/bug-1702396-add-share-servers-to-share-network-details-1cff66010817f1a8.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1702396-add-share-servers-to-share-network-details-1cff660100000664000175000017500000000032600000000000032224 0ustar00zuulzuul00000000000000--- fixes: - | Share servers are added to the share network details page. The page has been modified to show share servers and security services only if any exist, or are retrievable from the server. ././@PaxHeader0000000000000000000000000000021200000000000011450 xustar0000000000000000116 path=manila-ui-11.0.0/releasenotes/notes/bug-1702396-fix-cannot-get-share-network-details-83e2882df1714506.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1702396-fix-cannot-get-share-network-details-83e2882df1714500000664000175000017500000000067100000000000031616 0ustar00zuulzuul00000000000000--- fixes: - | Fixed an issue where an error message popped up about not being able to retrieve share network details when an ordinary user attempted to see these because the user wasn't authorized for certain admin-only ``share server`` information. In this circumstance we now handle this situation gracefully behind the scenes and display all the share network information for which the end user is authorized. ././@PaxHeader0000000000000000000000000000023200000000000011452 xustar0000000000000000132 path=manila-ui-11.0.0/releasenotes/notes/bug-1783232-fix-quotas-retrieval-for-shares-and-snapshots-tables-63a1fc877029eac8.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1783232-fix-quotas-retrieval-for-shares-and-snapshots-tables0000664000175000017500000000012000000000000033021 0ustar00zuulzuul00000000000000fixes: - | Fixed missing "Create Share" button on the "Shares" dashboard. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1787016-fix-share-replica-details-eecdc8b43f2a6008.yaml0000664000175000017500000000017300000000000031103 0ustar00zuulzuul00000000000000--- fixes: - | The Share replica details page has been fixed to render correctly for users with non-admin roles. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1823078-upgrade-api-to-v2.33-82871432659a8285.yaml0000664000175000017500000000027000000000000027044 0ustar00zuulzuul00000000000000--- fixes: - | This change updates the Manila API version to 2.33. This means that users can have access to timestamp details in access rules, available since API v2.33 ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=manila-ui-11.0.0/releasenotes/notes/bug-1842119-fix-get-quotas-for-update-quotas-share-7f229e4e011004cd.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1842119-fix-get-quotas-for-update-quotas-share-7f229e4e011000000664000175000017500000000016200000000000031717 0ustar00zuulzuul00000000000000--- fixes: - | Fixed issue that the saved Share quota data is not shown in Modify Quotas modal dialog. ././@PaxHeader0000000000000000000000000000021700000000000011455 xustar0000000000000000121 path=manila-ui-11.0.0/releasenotes/notes/bug-1931641-fix-handling-share-type-name-with-hyphens-8a9f16af36da5852.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1931641-fix-handling-share-type-name-with-hyphens-8a9f16af360000664000175000017500000000036300000000000032225 0ustar00zuulzuul00000000000000--- fixes: - | Visibility of "switchable" fields in the share creation form involving share types that had hyphens in their names is now fixed. See `Launchpad bug #1931641 `_ for more details. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1967312-fix-shares-panel-8b5da4eee68ba6c4.yaml0000664000175000017500000000022300000000000027407 0ustar00zuulzuul00000000000000--- fixes: - | `Bug #1967312 `_ that caused the shares dashboard to fail loading has now been fixed. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-1968925-fix-replica-creation-190321bf9fefe179.yaml0000664000175000017500000000021500000000000030045 0ustar00zuulzuul00000000000000--- fixes: - | `Bug #1968925 `_ that was preventing creation of share replicas has been fixed. ././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=manila-ui-11.0.0/releasenotes/notes/bug-2004165-fix-type-listing-when-rbac-enabled-c01f363dfa574b9b.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-2004165-fix-type-listing-when-rbac-enabled-c01f363dfa574b9b.0000664000175000017500000000035000000000000031645 0ustar00zuulzuul00000000000000--- fixes: - | Fixed an issue while trying to load share types that had boolean extra specs when RBAC was enabled. For more details, please refer to `Launchpad bug `_ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-2043572-fix-error-in-share-creation-1a8feef763c21b25.yaml0000664000175000017500000000024300000000000031312 0ustar00zuulzuul00000000000000--- fixes: - | Fixed error in share creation caused by internal UnicodeDecodeError. `Launchpad bug `_ ././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=manila-ui-11.0.0/releasenotes/notes/bug-873434-fix-set-as-active-button-visibility-e7cc416d66ab360b.yaml 22 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/bug-873434-fix-set-as-active-button-visibility-e7cc416d66ab360b.0000664000175000017500000000022600000000000032056 0ustar00zuulzuul00000000000000--- fixes: - | Visibility of Set as Active button for replicas in transitional states such as Deleting and Replication Change is now fixed. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/drop-python2-support-8f7cbc2c3a758777.yaml0000664000175000017500000000036000000000000026507 0ustar00zuulzuul00000000000000--- upgrade: - | Python 2.7 support has been dropped. The last release of openstack/manila-ui to support py2.7 is OpenStack Train (2.19.x). The minimum version of Python now supported by openstack/manila-ui is Python 3.6. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/field-encoder-update-7141766f0b5f8ecb.yaml0000664000175000017500000000025200000000000026376 0ustar00zuulzuul00000000000000--- fixes: - | Fixed an issue when share type with 'dhss=True' option and dash in the type name doesn't enable 'Share Network' widget at 'Create Share' form. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/filter-share-type-by-extra-spec-2.43-39710ce64f8be239.yaml0000664000175000017500000000011700000000000030753 0ustar00zuulzuul00000000000000--- features: - | Added filter search by extra spec for share type list. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/policy-in-code-support-23744e26a7f6e284.yaml0000664000175000017500000000042000000000000026603 0ustar00zuulzuul00000000000000--- upgrade: - | The default configuration file has been updated and now includes the required parameters to use the new policy-in-code feature in Horizon. Please refer to the release note and documentation of Horizon to find details about this feature. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/python-manilaclient-yoga-ef2c44b205fa216b.yaml0000664000175000017500000000030100000000000027363 0ustar00zuulzuul00000000000000--- upgrade: - | This version of manila-ui requires `python-manilaclient >= 2.7.0 `_ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/raise-python-manilaclient-version-9caa15ec2c94968d.yaml0000664000175000017500000000030500000000000031244 0ustar00zuulzuul00000000000000--- upgrade: - | This version of manila-ui requires `python-manilaclient >= 1.29.0 `_ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/remove-nova-net-plugin-4fdc0d944d93644f.yaml0000664000175000017500000000043700000000000026746 0ustar00zuulzuul00000000000000--- upgrade: - | Support for nova networking has been removed. Manila and the manilaclient sdk dropped support for nova network in the Ocata release (Feb 2017). So this should not have an impact on deployers running later releases, and this note is only informational. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/security-service-ou-field-2.44-c288a880b9b0fa68.yaml0000664000175000017500000000025600000000000030021 0ustar00zuulzuul00000000000000--- features: - | Added ‘ou’ field to ‘security_service’ object. Additionally added options to update dns_ip, ou, server, domain, password and user fields. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/share-shrinking-c1d46fc1c3ce29b7.yaml0000664000175000017500000000027400000000000025647 0ustar00zuulzuul00000000000000--- features: - | Existing "Extend Share" feature in Manila-UI was renamed "Resize Share" and share shrinking feature was added. Now users can both extend and shrink shares. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/notes/start-using-reno-49da440f5e237dda.yaml0000664000175000017500000000011500000000000025707 0ustar00zuulzuul00000000000000--- features: - Started using release notes to track changes to manila UI. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/0000775000175000017500000000000000000000000017461 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/2023.1.rst0000664000175000017500000000020200000000000020732 0ustar00zuulzuul00000000000000=========================== 2023.1 Series Release Notes =========================== .. release-notes:: :branch: stable/2023.1 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/2023.2.rst0000664000175000017500000000020200000000000020733 0ustar00zuulzuul00000000000000=========================== 2023.2 Series Release Notes =========================== .. release-notes:: :branch: stable/2023.2 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/_static/0000775000175000017500000000000000000000000021107 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/_static/.placeholder0000664000175000017500000000000000000000000023360 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/_templates/0000775000175000017500000000000000000000000021616 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/_templates/.placeholder0000664000175000017500000000000000000000000024067 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/conf.py0000664000175000017500000002140400000000000020761 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # 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. # manila-ui Release Notes documentation build configuration file, # created by sphinx-quickstart on Tue May 24 17:40:50 2016. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'reno.sphinxext', 'openstackdocstheme', ] # openstackdocsthem options openstackdocs_repo_name = 'openstack/manila-ui' openstackdocs_auto_name = False openstackdocs_bug_project = 'manila-ui' openstackdocs_bug_tag = 'release notes' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'manila-ui Release Notes' copyright = '2016, Manila Developers' # Release notes are version independent release = '' # The short X.Y version. version = '' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'ManilaUIReleaseNotesdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'ManilaUIReleaseNotes.tex', 'manila-ui Release Notes Documentation', 'Manila Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'manilauireleasenotes', 'manila-ui Release Notes Documentation', ['Manila Developers'], 1) ] # If true, show URL addresses after external links. # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'ManilaUIReleaseNotes', 'manila-ui Release Notes Documentation', 'Manila Developers', 'ManilaUIReleaseNotes', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/index.rst0000664000175000017500000000040200000000000021316 0ustar00zuulzuul00000000000000 ======================= manila-ui Release Notes ======================= .. toctree:: :maxdepth: 1 unreleased 2023.2 2023.1 zed yoga xena wallaby victoria ussuri train stein rocky queens pike ocata newton ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/0000775000175000017500000000000000000000000020720 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/de/0000775000175000017500000000000000000000000021310 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/de/LC_MESSAGES/0000775000175000017500000000000000000000000023075 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/de/LC_MESSAGES/releasenotes.po0000664000175000017500000001623300000000000026133 0ustar00zuulzuul00000000000000# Robert Simai , 2016. #zanata # Adriano Perri , 2017. #zanata # Andreas Jaeger , 2017. #zanata # Frank Kloeker , 2017. #zanata # Robert Simai , 2017. #zanata # Reik Keutterling , 2018. #zanata # Robert Simai , 2018. #zanata # Andreas Jaeger , 2019. #zanata # Andreas Jaeger , 2020. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-04-23 12:16+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2020-04-26 06:15+0000\n" "Last-Translator: Andreas Jaeger \n" "Language-Team: German\n" "Language: de\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "2.13.1" msgstr "2.13.1" msgid "2.16.0" msgstr "2.16.0" msgid "2.16.1" msgstr "2.16.1" msgid "2.16.2" msgstr "2.16.2" msgid "2.18.0" msgstr "2.18.0" msgid "2.18.1" msgstr "2.18.1" msgid "2.19.1" msgstr "2.19.1" msgid "2.2.0" msgstr "2.2.0" msgid "2.5.1-13" msgstr "2.5.1-13" msgid "2.7.0" msgstr "2.7.0" msgid "2.7.1" msgstr "2.7.1" msgid "2.8.0" msgstr "2.8.0" msgid "2.9.0" msgstr "2.9.0" msgid "3.0.0" msgstr "3.0.0" msgid "Added native protocol for MapRFS manila share driver" msgstr "Natives Protokoll für den MapRFS Manila Share Driver hinzugefügt" msgid "Added possibility to revert share to its latest snapshot." msgstr "" "Möglichkeit hinzugefügt, um das Share auf die letzte Schattenkopie " "zurückzusetzen." msgid "Added preserve-snapshots option to share migration." msgstr "Preserve-snapshots Option zum Teilen der Migration hinzugefügt." msgid "Added support for the mountable snapshots feature to manila-ui." msgstr "Unterstützung für mountbare Schattenkopien zur Manila UI hinzugefügt." msgid "" "Admin dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "Das Admin Dashboard hat jetzt eine manila-spezifische Panelgruppe " "'Freigabe'. Alle 'Tabs' von vorher sind jetzt Panele in dieser Gruppe. Jedes " "Panel wird mit einer eigenen Seite geladen. Dies erlaubt auf redundante API-" "Aufrufe zu verzichten, die beim gleichzeitigen Laden aller Tabs auftraten." msgid "Bug Fixes" msgstr "Fehlerkorrekturen" msgid "Current Series Release Notes" msgstr "Aktuelle Serie Releasenotes" msgid "Fixed Manage Replicas button availability." msgstr "Verfügbarkeit des Replika Verwalten Buttons gefixt." msgid "" "Fixed form of share creation from snapshot. Before it was losing source " "snapshot ID in request and was creating share from scratch instead of " "expected snapshot-sourced variant." msgstr "" "Feste Form der Freigabeerstellung aus Schattenkopie. Vorher war es in der " "Anfrage eine lose Quell-Schattenkopie-ID und die Freigabe wurden von scratch " "anstatt der erwarteten Quell-Schattenkopie-Variante erstellt." msgid "Fixed missing \"Create Share\" button on the \"Shares\" dashboard." msgstr "" "Fehlender \"Erstelle Share\" Button auf dem \"Shares\" Dashboard repariert." msgid "" "Fixed quota names overlapping with Cinder's quotas. Now it is possible to " "read/write any manila quotas not messing up Cinder's quotas." msgstr "" "Überlappung von Kontingentnamen mit Cinder korrigiert. Es sit jetzt möglich " "beliebige Manila-Kontingente zu lesen/schreiben, ohne die Cinder-Kontingente " "zu zerstören." msgid "New Features" msgstr "Neue Funktionen" msgid "Newton Series Release Notes" msgstr "Newton Serie Releasenotes" msgid "Ocata Series Release Notes" msgstr "Ocata Serie Releasenotes" msgid "Pike Series Release Notes" msgstr "Pike Serie Release Notes" msgid "" "Project dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "Projekt Dashboard hat nun eine manila-spezifische panel Gruppe namens \"share" "\". Alle \"Tabs\", die wir zuvor hatten sind nun panels in dieser Gruppe. " "Jeder panel wird auf einer separaten Seite geladen. Das erlaubt uns " "redundante API Aufrufe, welche wir beim Laden aller Tabs zur selben Zeit " "hatten, zu vermeiden." msgid "" "Python 2.7 support has been dropped. The last release of openstack/manila-ui " "to support py2.7 is OpenStack Train (2.19.x). The minimum version of Python " "now supported by openstack/manila-ui is Python 3.6." msgstr "" "Python 2.7 Unterstützung wurde beendet. Der letzte Release von manila-ui " "welcher Python 2.7 unterstützt ist OpenStack Train. Die minimal Python " "Version welche von manila-ui unterstützt wird ist Python 3.6." msgid "Queens Series Release Notes" msgstr "Versionshinweise Queens" msgid "Rocky Series Release Notes" msgstr "Rocky Serie Releasenotes" msgid "Started using release notes to track changes to manila UI." msgstr "" "Es wurde begonnen Releasenotes zu verwenden, um Änderungen der manila UI " "festzuhalten." msgid "Stein Series Release Notes" msgstr "Stein Serie Releasenotes" msgid "" "This version of manila-ui requires `python-manilaclient >= 1.29.0 `_" msgstr "" "Diese Version von manila-ui benötigt `python-manilaclient >= 1.29.0 " "`_" msgid "Train Series Release Notes" msgstr "Train Serie Releasenotes" msgid "" "URLs for resources in admin dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/admin/shares/" "share_networks/\" became - \"/admin/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "URLs für Resourcen im Admin-Dashboard wurden geändert. Ein Teil der Änderung " "ist das Löschen des mittleren \"Freigabe\"-Teils. Beispiel - aus - \"/admin/" "shares/share_networks/\" wurde - \"/admin/share_networks/\" Ein anderer Teil " "ist das Umbenennen von Resourcen gleichförmiger Aktionen." msgid "" "URLs for resources in project dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/project/shares/" "share_networks/\" became - \"/project/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "URLs für Resourcen im Admin-Dashboard wurden geändert. Ein Teil der Änderung " "ist das Löschen des mittleren \"Freigabe\"-Teils. Beispiel - aus - \"/admin/" "shares/share_networks/\" wurde - \"/admin/share_networks/\" Ein anderer Teil " "ist das Umbenennen von Resourcen gleichförmiger Aktionen." msgid "Updated descriptions of share migration parameters." msgstr "Beschreibungen zu Parametern für Share Migration hinzugefügt." msgid "Upgrade Notes" msgstr "Aktualisierungsnotizen" msgid "manila-ui Release Notes" msgstr "manila-ui Releasenotes" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/en_GB/0000775000175000017500000000000000000000000021672 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/en_GB/LC_MESSAGES/0000775000175000017500000000000000000000000023457 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po0000664000175000017500000004224400000000000026516 0ustar00zuulzuul00000000000000# Andi Chandler , 2017. #zanata # Andi Chandler , 2018. #zanata # Andi Chandler , 2019. #zanata # Andi Chandler , 2020. #zanata # Andi Chandler , 2022. #zanata # Andi Chandler , 2023. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui Release Notes\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-08-02 22:25+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2023-09-09 10:44+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en_GB\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "" "\"snapshot_support\" is no longer automatically included as an extra-spec in " "share types created via manila-ui. If the share type has to match backends " "that support snapshots, explicitly specify \"snapshot_support\" in the " "\"Extra specs\" field while creating share types. This change does not " "modify pre-existing share types." msgstr "" "\"snapshot_support\" is no longer automatically included as an extra-spec in " "share types created via Manila-UI. If the share type has to match backends " "that support snapshots, explicitly specify \"snapshot_support\" in the " "\"Extra specs\" field while creating share types. This change does not " "modify pre-existing share types." msgid "2.13.1" msgstr "2.13.1" msgid "2.16.0" msgstr "2.16.0" msgid "2.16.1" msgstr "2.16.1" msgid "2.16.2" msgstr "2.16.2" msgid "2.18.0" msgstr "2.18.0" msgid "2.18.1" msgstr "2.18.1" msgid "2.19.1" msgstr "2.19.1" msgid "2.19.2-6" msgstr "2.19.2-6" msgid "2.2.0" msgstr "2.2.0" msgid "2.5.1-13" msgstr "2.5.1-13" msgid "2.7.0" msgstr "2.7.0" msgid "2.7.1" msgstr "2.7.1" msgid "2.7.1-13" msgstr "2.7.1-13" msgid "2.8.0" msgstr "2.8.0" msgid "2.9.0" msgstr "2.9.0" msgid "2023.1 Series Release Notes" msgstr "2023.1 Series Release Notes" msgid "3.0.0" msgstr "3.0.0" msgid "3.1.0" msgstr "3.1.0" msgid "4.0.0" msgstr "4.0.0" msgid "4.1.0" msgstr "4.1.0" msgid "5.0.0" msgstr "5.0.0" msgid "5.1.0" msgstr "5.1.0" msgid "6.0.0" msgstr "6.0.0" msgid "7.0.0" msgstr "7.0.0" msgid "7.0.1" msgstr "7.0.1" msgid "8.0.0" msgstr "8.0.0" msgid "9.0.0" msgstr "9.0.0" msgid "" "Added access metadata for share access and also introduced the GET /share-" "access-rules API." msgstr "" "Added access metadata for share access and also introduced the GET /share-" "access-rules API." msgid "Added filter search by extra spec for share type list." msgstr "Added filter search by extra spec for share type list." msgid "Added native protocol for MapRFS manila share driver" msgstr "Added native protocol for MapRFS Manila share driver" msgid "Added possibility to create share type with description." msgstr "Added possibility to create share type with description." msgid "Added possibility to revert share to its latest snapshot." msgstr "Added possibility to revert share to its latest snapshot." msgid "Added preserve-snapshots option to share migration." msgstr "Added preserve-snapshots option to share migration." msgid "Added support for the mountable snapshots feature to manila-ui." msgstr "Added support for the mountable snapshots feature to Manila-UI." msgid "" "Added ‘is_default’ field to share types list. the Is_default Column will " "show 'Yes' if the share type is default share type." msgstr "" "Added ‘is_default’ field to share types list. the Is_default Column will " "show 'Yes' if the share type is the default share type." msgid "" "Added ‘ou’ field to ‘security_service’ object. Additionally added options to " "update dns_ip, ou, server, domain, password and user fields." msgstr "" "Added ‘ou’ field to ‘security_service’ object. Additionally added options to " "update dns_ip, ou, server, domain, password and user fields." msgid "" "Adds ‘is_default’ field to share group types list. the Is_default Column " "will show 'Yes' if the share group type is default share group type." msgstr "" "Adds ‘is_default’ field to share group types list. the Is_default Column " "will show 'Yes' if the share group type is default share group type." msgid "" "Admin dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "Admin dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgid "" "Availability zone field is now shown for both public and private shares in " "the dashboard showing detailed share information." msgstr "" "Availability zone field is now shown for both public and private shares in " "the dashboard showing detailed share information." msgid "Bug Fixes" msgstr "Bug Fixes" msgid "Current Series Release Notes" msgstr "Current Series Release Notes" msgid "" "Drop the ``host`` field from project view tables since this information is " "only visible to administrators. This is the UI side of `Launchpad bug " "1664370 `_ and completes the " "fix for that bug." msgstr "" "Drop the ``host`` field from project view tables since this information is " "only visible to administrators. This is the UI side of `Launchpad bug " "1664370 `_ and completes the " "fix for that bug." msgid "" "Existing \"Extend Share\" feature in Manila-UI was renamed \"Resize Share\" " "and share shrinking feature was added. Now users can both extend and shrink " "shares." msgstr "" "Existing \"Extend Share\" feature in Manila-UI was renamed \"Resize Share\" " "and share shrinking feature was added. Now users can both extend and shrink " "shares." msgid "Fixed Manage Replicas button availability." msgstr "Fixed Manage Replicas button availability." msgid "" "Fixed an issue when share type with 'dhss=True' option and dash in the type " "name doesn't enable 'Share Network' widget at 'Create Share' form." msgstr "" "Fixed an issue when share type with 'dhss=True' option and dash in the type " "name doesn't enable 'Share Network' widget at 'Create Share' form." msgid "" "Fixed an issue where an error message popped up about not being able to " "retrieve share network details when an ordinary user attempted to see these " "because the user wasn't authorized for certain admin-only ``share server`` " "information. In this circumstance we now handle this situation gracefully " "behind the scenes and display all the share network information for which " "the end user is authorized." msgstr "" "Fixed an issue where an error message popped up about not being able to " "retrieve share network details when an ordinary user attempted to see these " "because the user wasn't authorised for certain admin-only ``share server`` " "information. In this circumstance we now handle this situation gracefully " "behind the scenes and display all the share network information for which " "the end user is authorised." msgid "" "Fixed an issue while trying to load share types that had boolean extra specs " "when RBAC was enabled. For more details, please refer to `Launchpad bug " "`_" msgstr "" "Fixed an issue while trying to load share types that had boolean extra specs " "when RBAC was enabled. For more details, please refer to `Launchpad bug " "`_" msgid "" "Fixed form of share creation from snapshot. Before it was losing source " "snapshot ID in request and was creating share from scratch instead of " "expected snapshot-sourced variant." msgstr "" "Fixed form of share creation from snapshot. Before it was losing source " "snapshot ID in request and was creating share from scratch instead of " "expected snapshot-sourced variant." msgid "" "Fixed issue that the saved Share quota data is not shown in Modify Quotas " "modal dialog." msgstr "" "Fixed issue that the saved Share quota data is not shown in Modify Quotas " "modal dialogue." msgid "Fixed missing \"Create Share\" button on the \"Shares\" dashboard." msgstr "Fixed missing \"Create Share\" button on the \"Shares\" dashboard." msgid "" "Fixed quota names overlapping with Cinder's quotas. Now it is possible to " "read/write any manila quotas not messing up Cinder's quotas." msgstr "" "Fixed quota names overlapping with Cinder's quotas. Now it is possible to " "read/write any Manila quotas not messing up Cinder's quotas." msgid "IPv6 access rules can now be added to shares." msgstr "IPv6 access rules can now be added to shares." msgid "" "Implements the user messages graphical interface for the project and admin " "dashboards. [`blueprint ui-user-messages `_]" msgstr "" "Implements the user messages graphical interface for the project and admin " "dashboards. [`blueprint ui-user-messages `_]" msgid "New Features" msgstr "New Features" msgid "Newton Series Release Notes" msgstr "Newton Series Release Notes" msgid "Ocata Series Release Notes" msgstr "Ocata Series Release Notes" msgid "Pike Series Release Notes" msgstr "Pike Series Release Notes" msgid "" "Project dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "Project dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgid "" "Python 2.7 support has been dropped. The last release of openstack/manila-ui " "to support py2.7 is OpenStack Train (2.19.x). The minimum version of Python " "now supported by openstack/manila-ui is Python 3.6." msgstr "" "Python 2.7 support has been dropped. The last release of openstack/manila-ui " "to support py2.7 is OpenStack Train (2.19.x). The minimum version of Python " "now supported by openstack/manila-ui is Python 3.6." msgid "Queens Series Release Notes" msgstr "Queens Series Release Notes" msgid "Rocky Series Release Notes" msgstr "Rocky Series Release Notes" msgid "" "Share servers are added to the share network details page. The page has been " "modified to show share servers and security services only if any exist, or " "are retrievable from the server." msgstr "" "Share servers are added to the share network details page. The page has been " "modified to show share servers and security services only if any exist, or " "are retrievable from the server." msgid "Started using release notes to track changes to manila UI." msgstr "Started using release notes to track changes to Manila UI." msgid "Stein Series Release Notes" msgstr "Stein Series Release Notes" msgid "" "Support for nova networking has been removed. Manila and the manilaclient " "sdk dropped support for nova network in the Ocata release (Feb 2017). So " "this should not have an impact on deployers running later releases, and this " "note is only informational." msgstr "" "Support for nova networking has been removed. Manila and the manilaclient " "SDK dropped support for Nova-Network in the Ocata release (Feb 2017). So " "this should not have an impact on deployers running later releases, and this " "note is only informational." msgid "" "The Share replica details page has been fixed to render correctly for users " "with non-admin roles." msgstr "" "The Share replica details page has been fixed to render correctly for users " "with non-admin roles." msgid "" "The ``name``, ``description`` and/or ``share_type_access:is_public`` " "attributes of share types can be updated with API version ``2.50`` and " "beyond." msgstr "" "The ``name``, ``description`` and/or ``share_type_access:is_public`` " "attributes of share types can be updated with API version ``2.50`` and " "beyond." msgid "" "The default configuration file has been updated and now includes the " "required parameters to use the new policy-in-code feature in Horizon. Please " "refer to the release note and documentation of Horizon to find details about " "this feature." msgstr "" "The default configuration file has been updated and now includes the " "required parameters to use the new policy-in-code feature in Horizon. Please " "refer to the release note and documentation of Horizon to find details about " "this feature." msgid "" "The share groups dashboards now show the share group availability zone, " "share group type details and share group capabilities." msgstr "" "The share groups dashboards now show the share group availability zone, " "share group type details and share group capabilities." msgid "" "This change updates the Manila API version to 2.33. This means that users " "can have access to timestamp details in access rules, available since API " "v2.33" msgstr "" "This change updates the Manila API version to 2.33. This means that users " "can have access to timestamp details in access rules, available since API " "v2.33" msgid "" "This version of manila-ui requires `python-manilaclient >= 1.29.0 `_" msgstr "" "This version of manila-ui requires `python-manilaclient >= 1.29.0 `_" msgid "" "This version of manila-ui requires `python-manilaclient >= 2.7.0 `_" msgstr "" "This version of Manila-ui requires `python-manilaclient >= 2.7.0 `_" msgid "Train Series Release Notes" msgstr "Train Series Release Notes" msgid "" "URLs for resources in admin dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/admin/shares/" "share_networks/\" became - \"/admin/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "URLs for resources in admin dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/admin/shares/" "share_networks/\" became - \"/admin/share_networks/\" Other part is rename " "of resource actions to be more alike." msgid "" "URLs for resources in project dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/project/shares/" "share_networks/\" became - \"/project/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "URLs for resources in project dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/project/shares/" "share_networks/\" became - \"/project/share_networks/\" Other part is rename " "of resource actions to be more alike." msgid "Updated descriptions of share migration parameters." msgstr "Updated descriptions of share migration parameters." msgid "Upgrade Notes" msgstr "Upgrade Notes" msgid "Ussuri Series Release Notes" msgstr "Ussuri Series Release Notes" msgid "Victoria Series Release Notes" msgstr "Victoria Series Release Notes" msgid "" "Visibility of \"switchable\" fields in the share creation form involving " "share types that had hyphens in their names is now fixed. See `Launchpad bug " "#1931641 `_ for more details." msgstr "" "Visibility of \"switchable\" fields in the share creation form involving " "share types that had hyphens in their names is now fixed. See `Launchpad bug " "#1931641 `_ for more details." msgid "" "Visibility of Set as Active button for replicas in transitional states such " "as Deleting and Replication Change is now fixed." msgstr "" "Visibility of Set as Active button for replicas in transitional states such " "as Deleting and Replication Change is now fixed." msgid "Wallaby Series Release Notes" msgstr "Wallaby Series Release Notes" msgid "Xena Series Release Notes" msgstr "Xena Series Release Notes" msgid "Yoga Series Release Notes" msgstr "Yoga Series Release Notes" msgid "Zed Series Release Notes" msgstr "Zed Series Release Notes" msgid "" "`Bug #1967312 `_ that caused the shares " "dashboard to fail loading has now been fixed." msgstr "" "`Bug #1967312 `_ that caused the shares " "dashboard to fail loading has now been fixed." msgid "" "`Bug #1968925 `_ that was preventing " "creation of share replicas has been fixed." msgstr "" "`Bug #1968925 `_ that was preventing " "creation of share replicas has been fixed." msgid "manila-ui Release Notes" msgstr "Manila-UI Release Notes" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/fr/0000775000175000017500000000000000000000000021327 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/fr/LC_MESSAGES/0000775000175000017500000000000000000000000023114 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po0000664000175000017500000000174200000000000026151 0ustar00zuulzuul00000000000000# Gérald LONLAS , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui Release Notes 2.5.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-10-21 10:01+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-22 05:30+0000\n" "Last-Translator: Gérald LONLAS \n" "Language-Team: French\n" "Language: fr\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" msgid "2.2.0" msgstr "2.2.0" msgid "Current Series Release Notes" msgstr "Note de la release actuelle" msgid "New Features" msgstr "Nouvelles fonctionnalités" msgid "Newton Series Release Notes" msgstr "Note de release pour Newton" msgid "Started using release notes to track changes to manila UI." msgstr "" "Commence à utiliser les notes de Release pour suivre les changements de " "manila UI." msgid "manila-ui Release Notes" msgstr "Note de release de manila-ui" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/id/0000775000175000017500000000000000000000000021314 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/id/LC_MESSAGES/0000775000175000017500000000000000000000000023101 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/id/LC_MESSAGES/releasenotes.po0000664000175000017500000001332000000000000026131 0ustar00zuulzuul00000000000000# suhartono , 2016. #zanata # suhartono , 2017. #zanata # suhartono , 2018. #zanata # suhartono , 2019. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-09-16 12:05+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2019-03-12 06:02+0000\n" "Last-Translator: suhartono \n" "Language-Team: Indonesian\n" "Language: id\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.16.0" msgstr "2.16.0" msgid "2.2.0" msgstr "2.2.0" msgid "2.5.1-13" msgstr "2.5.1-13" msgid "2.7.0" msgstr "2.7.0" msgid "2.7.1" msgstr "2.7.1" msgid "2.8.0" msgstr "2.8.0" msgid "2.9.0" msgstr "2.9.0" msgid "Added native protocol for MapRFS manila share driver" msgstr "Ditambahkan protokol asli (native) untuk MapRFS manila share driver" msgid "Added possibility to revert share to its latest snapshot." msgstr "" "Ditambahkan kemungkinan untuk kembali share dengan snapshot terbarunya." msgid "Added preserve-snapshots option to share migration." msgstr "Ditambahkan opsi preserve-snapshots untuk berbagi migrasi." msgid "Added support for the mountable snapshots feature to manila-ui." msgstr "" "Dukungan yang ditambahkan untuk fitur mountable snapshots untuk manila-ui." msgid "" "Admin dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "Dasbor admin sekarang memiliki grup panel khusus manila yang disebut " "'share'. Semua 'tab' yang kami miliki sebelumnya adalah panel dalam grup ini " "sekarang. Setiap panel dimuat di halaman terpisah. Ini memungkinkan kita " "untuk menghindari pembuatan API yang berlebihan sehingga kita dapat " "melakukan pemuatan semua tab sekaligus." msgid "Bug Fixes" msgstr "Bug Fixes" msgid "Current Series Release Notes" msgstr "Current Series Release Notes (catatan rilis seri Current)" msgid "Fixed Manage Replicas button availability." msgstr "Fixed Manage Replicas button availability." msgid "" "Fixed form of share creation from snapshot. Before it was losing source " "snapshot ID in request and was creating share from scratch instead of " "expected snapshot-sourced variant." msgstr "" "Bentuk tetap pembuatan share dari snapshot. Sebelum kehilangan ID snapshot " "sumber dalam permintaan dan menciptakan share dari awal bukan varian " "snapshot yang diharapkan." msgid "Fixed missing \"Create Share\" button on the \"Shares\" dashboard." msgstr "Memperbaiki tombol \"Create Share\" yang hilang di dasbor \"Shares\"." msgid "" "Fixed quota names overlapping with Cinder's quotas. Now it is possible to " "read/write any manila quotas not messing up Cinder's quotas." msgstr "" "Nama kuota tetap tumpang tindih dengan kuota Cinder. Sekarang mungkin untuk " "membaca / menulis setiap kuota manila yang tidak mengacaukan kuota Cinder." msgid "New Features" msgstr "New Features (fitur baru)" msgid "Newton Series Release Notes" msgstr "Newton Series Release Notes (catatan rilis seri Newton)" msgid "Ocata Series Release Notes" msgstr "Ocata Series Release Notes" msgid "Pike Series Release Notes" msgstr "Catatan Rilis Seri Pike" msgid "" "Project dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "Dashboard proyek sekarang memiliki kelompok panel khusus manila yang disebut " "'share'. Semua 'tab' yang kami miliki sebelumnya adalah panel dalam grup ini " "sekarang. Setiap panel dimuat di halaman terpisah. Ini memungkinkan kita " "untuk menghindari pembuatan API yang berlebihan sehingga kita dapat " "melakukan pemuatan semua tab sekaligus." msgid "Queens Series Release Notes" msgstr "Catatan Rilis Seri Queens" msgid "Rocky Series Release Notes" msgstr "Catatan Rilis Seri Rocky" msgid "Started using release notes to track changes to manila UI." msgstr "Mulai menggunakan catatan rilis untuk melacak perubahan manila UI." msgid "" "URLs for resources in admin dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/admin/shares/" "share_networks/\" became - \"/admin/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "URL untuk sumber daya di dasbor admin telah diubah. Salah satu bagian dari " "perubahan adalah penghapusan bagian \"shares\" perantara. Contoh - was - \"/" "admin/shares/share_networks/\" menjadi - \"/admin/share_networks/\" Bagian " "lainnya adalah mengubah nama tindakan sumber daya menjadi lebih mirip." msgid "" "URLs for resources in project dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/project/shares/" "share_networks/\" became - \"/project/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "URL untuk sumber daya di dasbor proyek telah diubah. Salah satu bagian dari " "perubahan adalah penghapusan bagian \"shares\" perantara. Contoh- was - \"/" "project/shares/share_networks/\" menjadi - \"/project/share_networks/\" " "Bagian lainnya adalah mengubah nama tindakan sumber daya menjadi lebih mirip." msgid "Updated descriptions of share migration parameters." msgstr "Diperbarui deskripsi parameter share migration." msgid "Upgrade Notes" msgstr "Catatan Upgrade" msgid "manila-ui Release Notes" msgstr "Catatan rilis manila-ui " ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/ja/0000775000175000017500000000000000000000000021312 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/ja/LC_MESSAGES/0000775000175000017500000000000000000000000023077 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/ja/LC_MESSAGES/releasenotes.po0000664000175000017500000000164100000000000026132 0ustar00zuulzuul00000000000000# Shu Muto , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui Release Notes 2.7.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-03-21 16:11+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-06-16 05:49+0000\n" "Last-Translator: Shu Muto \n" "Language-Team: Japanese\n" "Language: ja\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.2.0" msgstr "2.2.0" msgid "Current Series Release Notes" msgstr "開発中バージョンのリリースノート" msgid "New Features" msgstr "新機能" msgid "Started using release notes to track changes to manila UI." msgstr "Manila UI の変更を追跡するため、リリースノートの使用を開始しました。" msgid "manila-ui Release Notes" msgstr "Manila UI リリースノート" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/ko_KR/0000775000175000017500000000000000000000000021725 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/ko_KR/LC_MESSAGES/0000775000175000017500000000000000000000000023512 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po0000664000175000017500000000404000000000000026541 0ustar00zuulzuul00000000000000# Ian Y. Choi , 2016. #zanata # minwook-shin , 2017. #zanata # Sungjin Kang , 2018. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-09-16 12:05+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2018-10-21 07:10+0000\n" "Last-Translator: Sungjin Kang \n" "Language-Team: Korean (South Korea)\n" "Language: ko_KR\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.16.0" msgstr "2.16.0" msgid "2.2.0" msgstr "2.2.0" msgid "2.5.1-13" msgstr "2.5.1-13" msgid "2.7.0" msgstr "2.7.0" msgid "2.7.1" msgstr "2.7.1" msgid "2.8.0" msgstr "2.8.0" msgid "2.9.0" msgstr "2.9.0" msgid "Added native protocol for MapRFS manila share driver" msgstr "MapRFS Manila 공유 드라이버에 대한 기본 프로토콜 추가" msgid "Added possibility to revert share to its latest snapshot." msgstr "최신 스냅샷으로 공유를 복구할 수 있는 기능 추가" msgid "Added preserve-snapshots option to share migration." msgstr "마이그레이션을 공하기위한 preserve-snapshots 옵션 추가" msgid "Added support for the mountable snapshots feature to manila-ui." msgstr "Manila-ui에 마운트가능한 스냅샷 기능에 대한 지원 추가" msgid "Bug Fixes" msgstr "버그 수정" msgid "Current Series Release Notes" msgstr "현재 시리즈에 대한 릴리즈 노트" msgid "New Features" msgstr "새로운 기능" msgid "Newton Series Release Notes" msgstr "Newton 시리즈에 대한 릴리즈 노트" msgid "Ocata Series Release Notes" msgstr "Ocata 시리즈에 대한 릴리즈 노트" msgid "Started using release notes to track changes to manila UI." msgstr "" "manilla UI 변경 사항을 추적하기 위해 릴리즈 노트 사용을 시작하였습니다." msgid "Upgrade Notes" msgstr "업그레이드 노트" msgid "manila-ui Release Notes" msgstr "manila-ui 릴리즈 노트" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/pt_BR/0000775000175000017500000000000000000000000021726 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/pt_BR/LC_MESSAGES/0000775000175000017500000000000000000000000023513 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/pt_BR/LC_MESSAGES/releasenotes.po0000664000175000017500000001321600000000000026547 0ustar00zuulzuul00000000000000# Fernando Pimenta , 2018. #zanata # Rodrigo Loures , 2018. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-10-09 02:25+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2018-03-02 08:07+0000\n" "Last-Translator: Fernando Pimenta \n" "Language-Team: Portuguese (Brazil)\n" "Language: pt_BR\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "2.2.0" msgstr "2.2.0" msgid "2.5.1-13" msgstr "2.5.1-13" msgid "2.7.0" msgstr "2.7.0" msgid "2.7.1" msgstr "2.7.1" msgid "2.8.0" msgstr "2.8.0" msgid "2.9.0" msgstr "2.9.0" msgid "Added native protocol for MapRFS manila share driver" msgstr "" "Adicionado protocolo nativo para o driver de compartilhamento manila MapRFS " msgid "Added possibility to revert share to its latest snapshot." msgstr "" "Adicionada a possibilidade de reverter um compartilhamento para o seu último " "snapshot." msgid "Added preserve-snapshots option to share migration." msgstr "Adicionada a opção preserve-snapshots à migração de snapshot." msgid "Added support for the mountable snapshots feature to manila-ui." msgstr "" "Adicionado suporte a funcionalidade de montagem de snapshots à manila-ui" msgid "" "Admin dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "O painel do administrador agora tem um grupo de painéis específicos do " "manila chamado 'compartilhamento'. Todas as 'abas' que tínhamos antes, agora " "são painéis nesse grupo. Cada painel é carregado em uma página separada. " "Isso nos permite evitar realizar chamadas redundantes de API que fizemos " "carregando todas as abas ao mesmo tempo." msgid "Bug Fixes" msgstr "Correção de erros" msgid "Current Series Release Notes" msgstr "Série Atual - Notas de Versão" msgid "Fixed Manage Replicas button availability." msgstr "Corrigida a disponibilidade do botão Gerenciar Réplicas." msgid "" "Fixed form of share creation from snapshot. Before it was losing source " "snapshot ID in request and was creating share from scratch instead of " "expected snapshot-sourced variant." msgstr "" "Corrigida a forma de criação de compartilhamento através de um snapshot. " "Antes era perdido o ID do snapshot de origem na solicitação e estava criando " "um compartilhamento do zero em vez de da variante esperada de snapshot " "originado de uma fonte." msgid "" "Fixed quota names overlapping with Cinder's quotas. Now it is possible to " "read/write any manila quotas not messing up Cinder's quotas." msgstr "" "Corrigida a sobreposição de nomes de quotas com quotas do Cinder. Agora é " "possível ler/gravar quaisquer quotas do manila sem bagunçar as quotas do " "Cinder." msgid "New Features" msgstr "Novos Recursos" msgid "Newton Series Release Notes" msgstr "Série Newton - Notas de Versão" msgid "Ocata Series Release Notes" msgstr "Série Ocata - Notas de Versão" msgid "Pike Series Release Notes" msgstr "Série Pike - Notas de Versão" msgid "" "Project dashboard now has manila-specific panel group called 'share'. All " "'tabs' we had before are panels in this group now. Each panel is loaded in " "separate page. It allows us to avoid making redundant API calls that we did " "loading all tabs at once." msgstr "" "O painel de projeto agora tem um grupo de painéis específicos do manila " "chamado 'compartilhamento'. Todas as 'abas' que tínhamos antes, agora são " "painéis nesse grupo. Cada painel é carregado em uma página separada. Isso " "nos permite evitar realizar chamadas redundantes de API que fizemos " "carregando todas as abas ao mesmo tempo." msgid "Queens Series Release Notes" msgstr "Série Queens - Notas de Versão" msgid "Started using release notes to track changes to manila UI." msgstr "" "Iniciado o uso de notas de versão para rastrear alterações no manila UI." msgid "" "URLs for resources in admin dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/admin/shares/" "share_networks/\" became - \"/admin/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "As URLs para recursos no painel do administrador foram alteradas. Uma parte " "das mudanças é a remoção da parte de \"compartilhamentos\" intermediários. " "Exemplo - O que era - \"/admin/shares/share_networks/\" torna-se - \"/admin/" "share_networks/\". Outra parte é o renomeação das ações de recursos para " "ficar mais adequado." msgid "" "URLs for resources in project dashboard were changed. One part of changes is " "removal of intermediate \"shares\" part. Example - was - \"/project/shares/" "share_networks/\" became - \"/project/share_networks/\" Other part is rename " "of resource actions to be more alike." msgstr "" "As URLs para recursos no painel de projetos foram alteradas. Uma parte das " "mudanças é a remoção da parte de \"compartilhamentos\" intermediários. " "Exemplo - O que era - \"/project/shares/share_networks/\" torna-se - \"/" "project/share_networks/\". Outra parte é o renomeação das ações de recursos " "para ficar mais adequado." msgid "Updated descriptions of share migration parameters." msgstr "Descrições atualizadas dos parâmetros de migração de compartilhamento." msgid "Upgrade Notes" msgstr "Notas de Atualização" msgid "manila-ui Release Notes" msgstr "Notas de Versão do manila-ui" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.7826514 manila-ui-11.0.0/releasenotes/source/locale/zh_CN/0000775000175000017500000000000000000000000021721 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/releasenotes/source/locale/zh_CN/LC_MESSAGES/0000775000175000017500000000000000000000000023506 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/locale/zh_CN/LC_MESSAGES/releasenotes.po0000664000175000017500000000352600000000000026545 0ustar00zuulzuul00000000000000# linlin <469923498@qq.com>, 2016. #zanata # sunanchen , 2016. #zanata # Bin , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: manila-ui Release Notes\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-02-28 14:05+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-07-27 03:57+0000\n" "Last-Translator: Bin \n" "Language-Team: Chinese (China)\n" "Language: zh_CN\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.2.0" msgstr "2.2.0版本" msgid "2.7.0" msgstr "2.7.0" msgid "2.7.1" msgstr "2.7.1" msgid "2.8.0" msgstr "2.8.0" msgid "2.9.0" msgstr "2.9.0" msgid "Added native protocol for MapRFS manila share driver" msgstr "为MapPFS的manila共享驱动添加本地协议。" msgid "Added possibility to revert share to its latest snapshot." msgstr "增加了将共享恢复到其最新快照的可能性。" msgid "Added preserve-snapshots option to share migration." msgstr "增加了共享迁移的保持快照选项。" msgid "Added support for the mountable snapshots feature to manila-ui." msgstr "增加了对manila-ui的可挂载快照特征支持。" msgid "Bug Fixes" msgstr "Bug修复" msgid "Current Series Release Notes" msgstr "当前版本发布说明" msgid "New Features" msgstr "新特性" msgid "Newton Series Release Notes" msgstr "Newton版本发布说明" msgid "Ocata Series Release Notes" msgstr "Ocata版本发布说明" msgid "Started using release notes to track changes to manila UI." msgstr "开始使用释放注释来追踪manila UI。" msgid "Updated descriptions of share migration parameters." msgstr "更新共享迁移参数的描述。" msgid "Upgrade Notes" msgstr "升级说明" msgid "manila-ui Release Notes" msgstr "manila-ui发布说明" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/newton.rst0000664000175000017500000000023200000000000021522 0ustar00zuulzuul00000000000000=================================== Newton Series Release Notes =================================== .. release-notes:: :branch: origin/stable/newton ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/ocata.rst0000664000175000017500000000023000000000000021275 0ustar00zuulzuul00000000000000=================================== Ocata Series Release Notes =================================== .. release-notes:: :branch: origin/stable/ocata ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/pike.rst0000664000175000017500000000017500000000000021146 0ustar00zuulzuul00000000000000========================== Pike Series Release Notes ========================== .. release-notes:: :branch: stable/pike ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/queens.rst0000664000175000017500000000022300000000000021510 0ustar00zuulzuul00000000000000=================================== Queens Series Release Notes =================================== .. release-notes:: :branch: stable/queens ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/rocky.rst0000664000175000017500000000022100000000000021335 0ustar00zuulzuul00000000000000=================================== Rocky Series Release Notes =================================== .. release-notes:: :branch: stable/rocky ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/stein.rst0000664000175000017500000000022100000000000021330 0ustar00zuulzuul00000000000000=================================== Stein Series Release Notes =================================== .. release-notes:: :branch: stable/stein ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/train.rst0000664000175000017500000000017600000000000021334 0ustar00zuulzuul00000000000000========================== Train Series Release Notes ========================== .. release-notes:: :branch: stable/train ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/unreleased.rst0000664000175000017500000000015300000000000022341 0ustar00zuulzuul00000000000000============================ Current Series Release Notes ============================ .. release-notes:: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/ussuri.rst0000664000175000017500000000020200000000000021537 0ustar00zuulzuul00000000000000=========================== Ussuri Series Release Notes =========================== .. release-notes:: :branch: stable/ussuri ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/victoria.rst0000664000175000017500000000022000000000000022025 0ustar00zuulzuul00000000000000============================= Victoria Series Release Notes ============================= .. release-notes:: :branch: unmaintained/victoria ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/wallaby.rst0000664000175000017500000000021400000000000021643 0ustar00zuulzuul00000000000000============================ Wallaby Series Release Notes ============================ .. release-notes:: :branch: unmaintained/wallaby ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/xena.rst0000664000175000017500000000020000000000000021136 0ustar00zuulzuul00000000000000========================= Xena Series Release Notes ========================= .. release-notes:: :branch: unmaintained/xena ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/yoga.rst0000664000175000017500000000020000000000000021142 0ustar00zuulzuul00000000000000========================= Yoga Series Release Notes ========================= .. release-notes:: :branch: unmaintained/yoga ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/releasenotes/source/zed.rst0000664000175000017500000000016600000000000021000 0ustar00zuulzuul00000000000000======================== Zed Series Release Notes ======================== .. release-notes:: :branch: stable/zed ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/requirements.txt0000664000175000017500000000073100000000000016755 0ustar00zuulzuul00000000000000# Requirements lower bounds listed here are our best effort to keep them up to # date but we do not test them so no guarantee of having them all correct. If # you find any incorrect lower bounds, let us know or propose a fix. pbr>=5.5.0 # Apache-2.0 # Horizon Core Requirements django-compressor>=2.0 # MIT iso8601>=0.1.12 # MIT oslo.utils>=4.7.0 # Apache-2.0 python-keystoneclient>=4.1.1 # Apache-2.0 python-manilaclient>=2.7.0 # Apache-2.0 horizon>=18.3.1 # Apache-2.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/run_tests.sh0000775000175000017500000004001700000000000016057 0ustar00zuulzuul00000000000000#!/bin/bash set -o errexit function usage { echo "Usage: $0 [OPTION]..." echo "Run Horizon's test suite(s)" echo "" echo " -V, --virtual-env Always use virtualenv. Install automatically" echo " if not present" echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local" echo " environment" echo " -c, --coverage Generate reports using Coverage" echo " -f, --force Force a clean re-build of the virtual" echo " environment. Useful when dependencies have" echo " been added." echo " -m, --manage Run a Django management command." echo " --makemessages Create/Update English translation files." echo " --compilemessages Compile all translation files." echo " --check-only Do not update translation files (--makemessages only)." echo " --pseudo Pseudo translate a language." echo " -p, --pep8 Just run pep8" echo " -8, --pep8-changed []" echo " Just run PEP8 and HACKING compliance check" echo " on files changed since HEAD~1 (or )" echo " -P, --no-pep8 Don't run pep8 by default" echo " -t, --tabs Check for tab characters in files." echo " -y, --pylint Just run pylint" echo " -q, --quiet Run non-interactively. (Relatively) quiet." echo " Implies -V if -N is not set." echo " --only-selenium Run only the Selenium unit tests" echo " --with-selenium Run unit tests including Selenium tests" echo " --selenium-headless Run Selenium tests headless" echo " --integration Run the integration tests (requires a running " echo " OpenStack environment)" echo " --runserver Run the Django development server for" echo " openstack_dashboard in the virtual" echo " environment." echo " --docs Just build the documentation" echo " --backup-environment Make a backup of the environment on exit" echo " --restore-environment Restore the environment before running" echo " --destroy-environment Destroy the environment and exit" echo " -h, --help Print this usage message" echo "" echo "Note: with no options specified, the script will try to run the tests in" echo " a virtual environment, If no virtualenv is found, the script will ask" echo " if you would like to create one. If you prefer to run tests NOT in a" echo " virtual environment, simply pass the -N option." exit } # DEFAULTS FOR RUN_TESTS.SH # root=`pwd -P` venv=$root/.venv venv_env_version=$venv/environments with_venv=tools/with_venv.sh included_dirs="manila_ui" always_venv=0 backup_env=0 command_wrapper="" destroy=0 force=0 just_pep8=0 just_pep8_changed=0 no_pep8=0 just_pylint=0 just_docs=0 just_tabs=0 never_venv=0 quiet=0 restore_env=0 runserver=0 only_selenium=0 with_selenium=0 selenium_headless=0 integration=0 testopts="" testargs="" with_coverage=0 makemessages=0 compilemessages=0 check_only=0 pseudo=0 manage=0 # Jenkins sets a "JOB_NAME" variable, if it's not set, we'll make it "default" [ "$JOB_NAME" ] || JOB_NAME="default" function process_option { # If running manage command, treat the rest of options as arguments. if [ $manage -eq 1 ]; then testargs="$testargs $1" return 0 fi case "$1" in -h|--help) usage;; -V|--virtual-env) always_venv=1; never_venv=0;; -N|--no-virtual-env) always_venv=0; never_venv=1;; -p|--pep8) just_pep8=1;; -8|--pep8-changed) just_pep8_changed=1;; -P|--no-pep8) no_pep8=1;; -y|--pylint) just_pylint=1;; -f|--force) force=1;; -t|--tabs) just_tabs=1;; -q|--quiet) quiet=1;; -c|--coverage) with_coverage=1;; -m|--manage) manage=1;; --makemessages) makemessages=1;; --compilemessages) compilemessages=1;; --check-only) check_only=1;; --pseudo) pseudo=1;; --only-selenium) only_selenium=1;; --with-selenium) with_selenium=1;; --selenium-headless) selenium_headless=1;; --integration) integration=1;; --docs) just_docs=1;; --runserver) runserver=1;; --backup-environment) backup_env=1;; --restore-environment) restore_env=1;; --destroy-environment) destroy=1;; -*) testopts="$testopts $1";; *) testargs="$testargs $1" esac } function run_management_command { ${command_wrapper} python $root/manage.py $testopts $testargs } function run_server { echo "Starting Django development server..." ${command_wrapper} python $root/manage.py runserver $testopts $testargs echo "Server stopped." } function run_pylint { echo "Running pylint ..." PYTHONPATH=$root ${command_wrapper} pylint --rcfile=.pylintrc -f parseable $included_dirs > pylint.txt || true CODE=$? grep Global -A2 pylint.txt if [ $CODE -lt 32 ]; then echo "Completed successfully." exit 0 else echo "Completed with problems." exit $CODE fi } function warn_on_flake8_without_venv { set +o errexit ${command_wrapper} python -c "import hacking" 2>/dev/null no_hacking=$? set -o errexit if [ $never_venv -eq 1 -a $no_hacking -eq 1 ]; then echo "**WARNING**:" >&2 echo "OpenStack hacking is not installed on your host. Its detection will be missed." >&2 echo "Please install or use virtual env if you need OpenStack hacking detection." >&2 fi } function run_pep8 { echo "Running flake8 ..." warn_on_flake8_without_venv DJANGO_SETTINGS_MODULE=manila_ui.tests.settings ${command_wrapper} flake8 } function run_pep8_changed { # NOTE(gilliard) We want use flake8 to check the entirety of every file that has # a change in it. Unfortunately the --filenames argument to flake8 only accepts # file *names* and there are no files named (eg) "nova/compute/manager.py". The # --diff argument behaves surprisingly as well, because although you feed it a # diff, it actually checks the file on disk anyway. local base_commit=${testargs:-HEAD~1} files=$(git diff --name-only $base_commit | tr '\n' ' ') echo "Running flake8 on ${files}" warn_on_flake8_without_venv diff -u --from-file /dev/null ${files} | DJANGO_SETTINGS_MODULE=manila_ui.tests.settings ${command_wrapper} flake8 --diff exit } function run_sphinx { echo "Building sphinx..." DJANGO_SETTINGS_MODULE=manila_ui.tests.settings ${command_wrapper} python setup.py build_sphinx echo "Build complete." } function tab_check { TAB_VIOLATIONS=`find $included_dirs -type f -regex ".*\.\(css\|js\|py\|html\)" -print0 | xargs -0 awk '/\t/' | wc -l` if [ $TAB_VIOLATIONS -gt 0 ]; then echo "TABS! $TAB_VIOLATIONS of them! Oh no!" HORIZON_FILES=`find $included_dirs -type f -regex ".*\.\(css\|js\|py|\html\)"` for TABBED_FILE in $HORIZON_FILES do TAB_COUNT=`awk '/\t/' $TABBED_FILE | wc -l` if [ $TAB_COUNT -gt 0 ]; then echo "$TABBED_FILE: $TAB_COUNT" fi done fi return $TAB_VIOLATIONS; } function destroy_venv { echo "Cleaning environment..." echo "Removing virtualenv..." rm -rf $venv echo "Virtualenv removed." } function environment_check { echo "Checking environment." if [ -f $venv_env_version ]; then set +o errexit cat requirements.txt test-requirements.txt | cmp $venv_env_version - > /dev/null local env_check_result=$? set -o errexit if [ $env_check_result -eq 0 ]; then # If the environment exists and is up-to-date then set our variables command_wrapper="${root}/${with_venv}" echo "Environment is up to date." return 0 fi fi if [ $always_venv -eq 1 ]; then install_venv else if [ ! -e ${venv} ]; then echo -e "Environment not found. Install? (Y/n) \c" else echo -e "Your environment appears to be out of date. Update? (Y/n) \c" fi read update_env if [ "x$update_env" = "xY" -o "x$update_env" = "x" -o "x$update_env" = "xy" ]; then install_venv else # Set our command wrapper anyway. command_wrapper="${root}/${with_venv}" fi fi } function sanity_check { # Anything that should be determined prior to running the tests, server, etc. # Don't sanity-check anything environment-related in -N flag is set if [ $never_venv -eq 0 ]; then if [ ! -e ${venv} ]; then echo "Virtualenv not found at $venv. Did install_venv.py succeed?" exit 1 fi fi # Remove .pyc files. This is sanity checking because they can linger # after old files are deleted. find . -name "*.pyc" -exec rm -rf {} \; } function backup_environment { if [ $backup_env -eq 1 ]; then echo "Backing up environment \"$JOB_NAME\"..." if [ ! -e ${venv} ]; then echo "Environment not installed. Cannot back up." return 0 fi if [ -d /tmp/.horizon_environment/$JOB_NAME ]; then mv /tmp/.horizon_environment/$JOB_NAME /tmp/.horizon_environment/$JOB_NAME.old rm -rf /tmp/.horizon_environment/$JOB_NAME fi mkdir -p /tmp/.horizon_environment/$JOB_NAME cp -r $venv /tmp/.horizon_environment/$JOB_NAME/ # Remove the backup now that we've completed successfully rm -rf /tmp/.horizon_environment/$JOB_NAME.old echo "Backup completed" fi } function restore_environment { if [ $restore_env -eq 1 ]; then echo "Restoring environment from backup..." if [ ! -d /tmp/.horizon_environment/$JOB_NAME ]; then echo "No backup to restore from." return 0 fi cp -r /tmp/.horizon_environment/$JOB_NAME/.venv ./ || true echo "Environment restored successfully." fi } function install_venv { # Install with install_venv.py export PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE-/tmp/.pip_download_cache} export PIP_USE_MIRRORS=true if [ $quiet -eq 1 ]; then export PIP_NO_INPUT=true fi echo "Fetching new src packages..." rm -rf $venv/src python tools/install_venv.py command_wrapper="$root/${with_venv}" # Make sure it worked and record the environment version sanity_check chmod -R 754 $venv cat requirements.txt test-requirements.txt > $venv_env_version } function run_tests { sanity_check if [ $with_selenium -eq 1 ]; then export WITH_SELENIUM=1 elif [ $only_selenium -eq 1 ]; then export WITH_SELENIUM=1 export SKIP_UNITTESTS=1 fi if [ $selenium_headless -eq 1 ]; then export SELENIUM_HEADLESS=1 fi if [ -z "$testargs" ]; then run_tests_all else run_tests_subset fi } function run_tests_subset { project=`echo $testargs | awk -F. '{print $1}'` ${command_wrapper} python $root/manage.py test --settings=$project.tests.settings --exclude-tag integration $testopts $testargs } function run_tests_all { echo "Running Manila-UI application tests" export NOSE_XUNIT_FILE=manila_ui/nosetests.xml if [ "$NOSE_WITH_HTML_OUTPUT" = '1' ]; then export NOSE_HTML_OUT_FILE='manila_ui_nose_results.html' fi if [ $with_coverage -eq 1 ]; then ${command_wrapper} python -m coverage.__main__ erase coverage_run="python -m coverage.__main__ run -p" fi ${command_wrapper} ${coverage_run} $root/manage.py test manila_ui --settings=manila_ui.tests.settings --exclude-tag integration $testopts # get results of the Horizon tests MANILA_UI_RESULT=$? if [ $with_coverage -eq 1 ]; then echo "Generating coverage reports" ${command_wrapper} python -m coverage.__main__ combine ${command_wrapper} python -m coverage.__main__ xml -i --omit='/usr*,setup.py,*egg*,.venv/*' ${command_wrapper} python -m coverage.__main__ html -i --omit='/usr*,setup.py,*egg*,.venv/*' -d cover fi # Remove the leftover coverage files from the -p flag earlier. rm -f .coverage.* PEP8_RESULT=0 if [ $no_pep8 -eq 0 ] && [ $only_selenium -eq 0 ]; then run_pep8 PEP8_RESULT=$? fi TEST_RESULT=$(($MANILA_UI_RESULT || $PEP8_RESULT)) if [ $TEST_RESULT -eq 0 ]; then echo "Tests completed successfully." else echo "Tests failed." fi exit $TEST_RESULT } function run_integration_tests { export INTEGRATION_TESTS=1 if [ $selenium_headless -eq 1 ]; then export SELENIUM_HEADLESS=1 fi echo "Running Horizon integration tests..." if [ -z "$testargs" ]; then ${command_wrapper} nosetests openstack_dashboard/test/integration_tests/tests else ${command_wrapper} nosetests $testargs fi exit 0 } function run_makemessages { OPTS="-l en --no-obsolete --settings=openstack_dashboard.test.settings" DASHBOARD_OPTS="--extension=html,txt,csv --ignore=openstack" echo -n "horizon: " cd horizon ${command_wrapper} $root/manage.py makemessages $OPTS HORIZON_PY_RESULT=$? echo -n "horizon javascript: " ${command_wrapper} $root/manage.py makemessages -d djangojs $OPTS HORIZON_JS_RESULT=$? echo -n "openstack_dashboard: " cd ../openstack_dashboard ${command_wrapper} $root/manage.py makemessages $DASHBOARD_OPTS $OPTS DASHBOARD_RESULT=$? cd .. if [ $check_only -eq 1 ]; then git checkout -- horizon/locale/en/LC_MESSAGES/django*.po git checkout -- openstack_dashboard/locale/en/LC_MESSAGES/django.po fi exit $(($HORIZON_PY_RESULT || $HORIZON_JS_RESULT || $DASHBOARD_RESULT)) } function run_compilemessages { OPTS="--settings=openstack_dashboard.test.settings" cd horizon ${command_wrapper} $root/manage.py compilemessages $OPTS HORIZON_PY_RESULT=$? cd ../openstack_dashboard ${command_wrapper} $root/manage.py compilemessages $OPTS DASHBOARD_RESULT=$? cd .. # English is the source language, so compiled catalogs are unnecessary. rm -vf horizon/locale/en/LC_MESSAGES/django*.mo rm -vf openstack_dashboard/locale/en/LC_MESSAGES/django.mo exit $(($HORIZON_PY_RESULT || $DASHBOARD_RESULT)) } function run_pseudo { for lang in $testargs # Use English po file as the source file/pot file just like real Horizon translations do ${command_wrapper} $root/tools/pseudo.py openstack_dashboard/locale/en/LC_MESSAGES/django.po openstack_dashboard/locale/$lang/LC_MESSAGES/django.po $lang ${command_wrapper} $root/tools/pseudo.py horizon/locale/en/LC_MESSAGES/django.po horizon/locale/$lang/LC_MESSAGES/django.po $lang ${command_wrapper} $root/tools/pseudo.py horizon/locale/en/LC_MESSAGES/djangojs.po horizon/locale/$lang/LC_MESSAGES/djangojs.po $lang done exit $? } # ---------PREPARE THE ENVIRONMENT------------ # # PROCESS ARGUMENTS, OVERRIDE DEFAULTS for arg in "$@"; do process_option $arg done if [ $quiet -eq 1 ] && [ $never_venv -eq 0 ] && [ $always_venv -eq 0 ] then always_venv=1 fi # If destroy is set, just blow it away and exit. if [ $destroy -eq 1 ]; then destroy_venv exit 0 fi # Ignore all of this if the -N flag was set if [ $never_venv -eq 0 ]; then # Restore previous environment if desired if [ $restore_env -eq 1 ]; then restore_environment fi # Remove the virtual environment if --force used if [ $force -eq 1 ]; then destroy_venv fi # Then check if it's up-to-date environment_check # Create a backup of the up-to-date environment if desired if [ $backup_env -eq 1 ]; then backup_environment fi fi # ---------EXERCISE THE CODE------------ # # Run management commands if [ $manage -eq 1 ]; then run_management_command exit $? fi # Build the docs if [ $just_docs -eq 1 ]; then run_sphinx exit $? fi # Update translation files if [ $makemessages -eq 1 ]; then run_makemessages exit $? fi # Compile translation files if [ $compilemessages -eq 1 ]; then run_compilemessages exit $? fi # Generate Pseudo translation if [ $pseudo -eq 1 ]; then run_pseudo exit $? fi # PEP8 if [ $just_pep8 -eq 1 ]; then run_pep8 exit $? fi if [ $just_pep8_changed -eq 1 ]; then run_pep8_changed exit $? fi # Pylint if [ $just_pylint -eq 1 ]; then run_pylint exit $? fi # Tab checker if [ $just_tabs -eq 1 ]; then tab_check exit $? fi # Integration tests if [ $integration -eq 1 ]; then run_integration_tests exit $? fi # Django development server if [ $runserver -eq 1 ]; then run_server exit $? fi # Full test suite run_tests || exit ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8586514 manila-ui-11.0.0/setup.cfg0000664000175000017500000000166600000000000015322 0ustar00zuulzuul00000000000000[metadata] name = manila-ui summary = Manila Management Dashboard description_file = README.rst author = OpenStack author_email = openstack-discuss@lists.openstack.org home_page = https://docs.openstack.org/manila-ui/latest/ python_requires = >=3.6 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.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 [files] packages = manila_ui [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/setup.py0000664000175000017500000000127100000000000015203 0ustar00zuulzuul00000000000000# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # 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 setuptools setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/test-requirements.txt0000664000175000017500000000051700000000000017734 0ustar00zuulzuul00000000000000hacking>=6.1.0,<6.2.0 # Apache-2.0 coverage>=5.2.1 # Apache-2.0 ddt>=1.4.1 # MIT python-subunit>=1.4.0 # Apache-2.0/BSD pytest>=5.3.5 # MIT testrepository>=0.0.20 # Apache-2.0/BSD testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.4.0 # MIT # integration tests requirements selenium>=2.50.1 # Apache-2.0 xvfbwrapper>=0.1.3 #license: MIT ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1712145162.8546515 manila-ui-11.0.0/tools/0000775000175000017500000000000000000000000014630 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/tools/cover.sh0000775000175000017500000000453300000000000016312 0ustar00zuulzuul00000000000000#!/bin/bash # # Copyright 2015: Mirantis Inc. # 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. ALLOWED_EXTRA_MISSING=4 TESTR_ARGS="$*" show_diff () { head -1 $1 diff -U 0 $1 $2 | sed 1,2d } # # Stash uncommitted changes, checkout master and save coverage report uncommitted=$(git status --porcelain | grep -v "^??") [[ -n $uncommitted ]] && git stash > /dev/null git checkout HEAD^ baseline_report=$(mktemp -t manila_coverageXXXXXXX) find . -type f -name "*.pyc" -delete && ./run_tests.sh -N --coverage --no-pep8 $TESTR_ARGS coverage report > $baseline_report baseline_missing=$(awk 'END { print $3 }' $baseline_report) # Checkout back and unstash uncommitted changes (if any) git checkout - [[ -n $uncommitted ]] && git stash pop > /dev/null # Generate and save coverage report current_report=$(mktemp -t manila_coverageXXXXXXX) find . -type f -name "*.pyc" -delete && ./run_tests.sh -N --coverage --no-pep8 $TESTR_ARGS coverage report > $current_report current_missing=$(awk 'END { print $3 }' $current_report) # Show coverage details allowed_missing=$((baseline_missing+ALLOWED_EXTRA_MISSING)) echo "Allowed to introduce missing lines : ${ALLOWED_EXTRA_MISSING}" echo "Missing lines in master : ${baseline_missing}" echo "Missing lines in proposed change : ${current_missing}" if [ $allowed_missing -gt $current_missing ]; then if [ $baseline_missing -lt $current_missing ]; then show_diff $baseline_report $current_report echo "I believe you can cover all your code with 100% coverage!" else echo "Thank you! You are awesome! Keep writing unit tests! :)" fi exit_code=0 else show_diff $baseline_report $current_report echo "Please write more unit tests, we should keep our test coverage :( " exit_code=1 fi rm $baseline_report $current_report exit $exit_code ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/tools/with_venv.sh0000775000175000017500000000033200000000000017176 0ustar00zuulzuul00000000000000#!/bin/bash TOOLS_PATH=${TOOLS_PATH:-$(dirname $0)} VENV_PATH=${VENV_PATH:-${TOOLS_PATH}} VENV_DIR=${VENV_NAME:-/../.venv} TOOLS=${TOOLS_PATH} VENV=${VENV:-${VENV_PATH}/${VENV_DIR}} source ${VENV}/bin/activate && "$@" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1712145119.0 manila-ui-11.0.0/tox.ini0000664000175000017500000000513500000000000015007 0ustar00zuulzuul00000000000000[tox] minversion = 3.18.0 envlist = py39,pep8 ignore_basepython_conflict = true [testenv] basepython = python3 usedevelop = True setenv = VIRTUAL_ENV={envdir} deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt allowlist_externals = /bin/bash commands = /bin/bash run_tests.sh -N --no-pep8 {posargs} [testenv:py36] setenv = DJANGO_SETTINGS_MODULE=manila_ui.tests.settings [testenv:py37] setenv = DJANGO_SETTINGS_MODULE=manila_ui.tests.settings [testenv:py38] setenv = DJANGO_SETTINGS_MODULE=manila_ui.tests.settings [testenv:py3-dev] setenv = DJANGO_SETTINGS_MODULE=manila_ui.tests.settings commands = pip install {env:HORIZON_REPO:git+https://opendev.org/openstack/horizon} {[testenv]commands} [testenv:integration] # Run integration tests only passenv = AVCONV_INSTALLED setenv = PYTHONHASHSEED=0 INTEGRATION_TESTS=1 SELENIUM_HEADLESS=1 HORIZON_INTEGRATION_TESTS_CONFIG_FILE=manila_ui/tests/integration/horizon.conf commands = {envpython} {toxinidir}/manage.py test manila_ui --settings=manila_ui.tests.settings --tag integration [testenv:newnote] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt commands = reno new {posargs} [testenv:pep8] commands = flake8 [testenv:venv] commands = {posargs} [testenv:cover] allowlist_externals = {toxinidir}/tools/cover.sh commands = {toxinidir}/tools/cover.sh {posargs} [testenv:docs] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt allowlist_externals = rm commands = rm -rf doc/build sphinx-build -W -b html doc/source doc/build/html [testenv:pdf-docs] deps={[testenv:docs]deps} usedevelop = True allowlist_externals = make commands = sphinx-build -W -b latex doc/source doc/build/pdf make -C doc/build/pdf [testenv:releasenotes] commands = sphinx-build -a -E -W -d releasenotes/build/doctrees \ -b html releasenotes/source releasenotes/build/html [testenv:debug] commands = oslo_debug_helper {posargs} [flake8] show-source = True # E123, E125 skipped as they are invalid PEP-8. # F405 TEMPLATES may be undefined, or defined from star imports # (because it is not easy to avoid this in openstack_dashboard.test.settings) # H405 multi line docstring summary not separated with an empty line # W504 line break after binary operator ignore = E123,E125,F405,H405,W504 enable-extensions = H203,H106 exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,.ropeproject,tools