ironic-ui-2.2.0/0000775000567000056710000000000013046166505014560 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/manage.py0000775000567000056710000000155013046166232016363 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2016 Cisco Systems, 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 os import sys from django.core.management import execute_from_command_line # noqa if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ironic_ui.test.settings") execute_from_command_line(sys.argv) ironic-ui-2.2.0/babel-django.cfg0000664000567000056710000000020513046166232017540 0ustar jenkinsjenkins00000000000000[extractors] django = django_babel.extract:extract_django [python: **.py] [django: templates/**.html] [django: **/templates/**.csv] ironic-ui-2.2.0/LICENSE0000664000567000056710000002363713046166232015575 0ustar jenkinsjenkins00000000000000 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. ironic-ui-2.2.0/MANIFEST.in0000664000567000056710000000023713046166232016315 0ustar jenkinsjenkins00000000000000include AUTHORS include ChangeLog exclude .gitignore exclude .gitreview include setup.py recursive-include ironic_ui *.js *.html *.scss global-exclude *.pyc ironic-ui-2.2.0/.testr.conf0000664000567000056710000000047713046166232016653 0ustar jenkinsjenkins00000000000000[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 ironic-ui-2.2.0/HACKING.rst0000664000567000056710000000024113046166232016350 0ustar jenkinsjenkins00000000000000ironic-ui Style Commandments =============================================== Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/ ironic-ui-2.2.0/releasenotes/0000775000567000056710000000000013046166505017251 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/notes/0000775000567000056710000000000013046166505020401 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/notes/.placeholder0000664000567000056710000000000013046166232022647 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/notes/bug-1648557-462ebfdf39efee1f.yaml0000664000567000056710000000043713046166232025434 0ustar jenkinsjenkins00000000000000--- features: - | The user is now able to abort a node cleaning operation. When cleaning is aborted the node is moved from the ``CLEAN WAIT`` state to the ``CLEAN FAIL`` state. When appropriate an "Abort cleaning" action will be present in individual node action menu. ironic-ui-2.2.0/releasenotes/notes/bug-1648563-e2bc262985873122.yaml0000664000567000056710000000042113046166232024672 0ustar jenkinsjenkins00000000000000--- features: - | The node-details/configuration page has been extended to enable the user to edit ports after initial creation. - | The user is now able to specify the pxe_enabled and local-link-connection attributes as part of defining/editing ports. ironic-ui-2.2.0/releasenotes/notes/bug-1648550-32e28cf2a401bb02.yaml0000664000567000056710000000021013046166232025052 0ustar jenkinsjenkins00000000000000--- features: - | The current cleaning step is displayed in the Provisioning Status section of the node-details/overview page ironic-ui-2.2.0/releasenotes/notes/2.1.0-release-3391dfbcf087c883.yaml0000664000567000056710000000101413046166232025561 0ustar jenkinsjenkins00000000000000--- prelude: > This release adds support for editing nodes and moving those nodes between enroll, manageable, available and active states. It is now possible to enroll a node without all required fields for moving to manageable state being present due to the facility for editing the node once it has been created. features: - Edit nodes after creation - Move nodes between enroll, manageable, available and active states - Ability to enroll a node without all required fields for other states ironic-ui-2.2.0/releasenotes/notes/2.0-release-3d8acae7c8de429b.yaml0000664000567000056710000000155613046166232025650 0ustar jenkinsjenkins00000000000000--- prelude: > This release adds support for adding and deleting nodes. Support has also been added for adding and deleting ports. The panel will now be hidden if the baremetal service is not present in the scenario where the collection of running services differs between multiple keystone regions. features: - Add and delete nodes - Add and delete ports - Panel hidden if baremetal service or admin rights are not present - UX improvements across the interface - Breadcrumbs have been added issues: - Currently it is not possible to edit a node via the UI once it has been enrolled. Therefore, the enrollment must be done accurately to ensure the node is enrolled accurately and can then be made available. At present, any errors made during enrollment can only be corrected by deleting the node and enrolling it again. ironic-ui-2.2.0/releasenotes/notes/bug-1648548-6e846a0c1e1574aa.yaml0000664000567000056710000000036713046166232025115 0ustar jenkinsjenkins00000000000000--- features: - | Support has been added for inspecting nodes. For a node that is in the ``manageable`` state, its action menu will include an ``Inspect`` button. Node action menus are located in the node-list and node-detail pages. ironic-ui-2.2.0/releasenotes/source/0000775000567000056710000000000013046166505020551 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/current-series.rst0000664000567000056710000000015313046166232024251 0ustar jenkinsjenkins00000000000000============================ Current Series Release Notes ============================ .. release-notes:: ironic-ui-2.2.0/releasenotes/source/_static/0000775000567000056710000000000013046166505022177 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/_static/.placeholder0000664000567000056710000000000013046166232024445 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/0000775000567000056710000000000013046166505022010 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/de/0000775000567000056710000000000013046166505022400 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/de/LC_MESSAGES/0000775000567000056710000000000013046166505024165 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/de/LC_MESSAGES/releasenotes.po0000664000567000056710000000735313046166232027223 0ustar jenkinsjenkins00000000000000# Robert Simai , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-11-14 13:58+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-14 04:37+0000\n" "Last-Translator: Robert Simai \n" "Language-Team: German\n" "Language: de\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "2.0.0" msgstr "2.0.0" msgid "2.1.0" msgstr "2.1.0" msgid "Ability to enroll a node without all required fields for other states" msgstr "" "Möglichkeit, einen Knoten ohne alle notwendigen Felder für weitere Zustände " "anzumelden" msgid "Add and delete nodes" msgstr "Hinzufügen und Löschen von Knoten" msgid "Add and delete ports" msgstr "Hinzufügen und Löschen von Ports" msgid "Breadcrumbs have been added" msgstr "Breadcrumbs wurden hinzugefügt" msgid "Current Series Release Notes" msgstr "Aktuelle Serie Releasenotes" msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "Es ist gegenwärtig nicht möglich einen Knoten zu bearbeiten, nachdem er " "angemeldet wurde. Die Anmeldung muss daher sorgfältig durchgeführt werden, " "so dass der Knoten verfügbar gemacht werden kann. Jeglicher Fehler kann " "derzeit nur durch löschen und neu anlegen des Knotens und einen neue " "Anmeldung behoben werden." msgid "Edit nodes after creation" msgstr "Knoten nach Erstellung bearbeiten" msgid "Ironic UI Release Notes" msgstr "Ironic UI Releasenotes" msgid "Known Issues" msgstr "Bekannte Probleme" msgid "Move nodes between enroll, manageable, available and active states" msgstr "Knoten zwischen anmelden, verwaltbar und aktiv Zuständen bewegen" msgid "New Features" msgstr "Neue Funktionen" msgid "Newton Series Release Notes" msgstr "Newton Serie Releasenotes" msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "" "Paneel wird versteckt, wenn Baremetal-Dienst oder Administratorenrechte " "fehlen" msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "Dieses Release fügt Unterstützung zum Hinzufügen und Löschen von Knoten " "hinzu, ebenso wie die Unterstützung zum Hinzufügen und Löschen von Ports. " "Das Paneel wird jetzt versteckt, wenn der Baremetal-Dienst im Szenario " "fehlt, in dem die Sammlung der laufenden Dienste sich zwischen multiplen " "Keystone-Regionen unterscheidet." msgid "" "This release adds support for editing nodes and moving those nodes between " "enroll, manageable, available and active states. It is now possible to " "enroll a node without all required fields for moving to manageable state " "being present due to the facility for editing the node once it has been " "created." msgstr "" "Dieses Release fügt Unterstützung zum Bearbeiten von Knoten sowie zum " "Bewegen der Knoten zwischen anmelden, verwaltbar und aktiv-Zustand hinzu. Es " "ist jetzt möglich, einen Knoten ohne Angabe aller erforderlicher Felder in " "den verwaltbar Zustand zu bewegen. Dies geschieht durch die Möglichkeit zum " "bearbeiten des Knotens, nachdem er erstellt wurde." msgid "UX improvements across the interface" msgstr "UX-Verbesserungen im Interface" ironic-ui-2.2.0/releasenotes/source/locale/ru/0000775000567000056710000000000013046166505022436 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/ru/LC_MESSAGES/0000775000567000056710000000000013046166505024223 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/ru/LC_MESSAGES/releasenotes.po0000664000567000056710000001157413046166232027261 0ustar jenkinsjenkins00000000000000# Yulia Ryndenkova , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-10-07 16:48+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-20 05:44+0000\n" "Last-Translator: Yulia Ryndenkova \n" "Language-Team: Russian\n" "Language: ru\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" msgid "2.0.0" msgstr "2.0.0" msgid "2.1.0" msgstr "2.1.0" msgid "Ability to enroll a node without all required fields for other states" msgstr "" "Возможность зарегистрировать узел без обязательных полей для других состояний" msgid "Add and delete nodes" msgstr "Добавить и удалить узлы" msgid "Add and delete ports" msgstr "Добавить и удалить порты" msgid "Breadcrumbs have been added" msgstr "Добавлены строки навигации" msgid "Current Series Release Notes" msgstr "Примечания к выпуску Current Series " msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "В настоящее время отсутствует возможно редактирования узла через UI после " "его регистрации. Поэтому регистрация должна проходить безошибочно, для того " "чтобы убедиться что узел корректно зарегистрирован и позже будет доступен. В " "настоящее время, любые ошибки во время регистрации могут быть исправлены " "только посредством удаления и перерегистрации узла." msgid "Edit nodes after creation" msgstr "Редактирование узла после создания" msgid "Ironic UI Release Notes" msgstr "Примечания к выпуску Ironic UI " msgid "Known Issues" msgstr "Известные Проблемы" msgid "Move nodes between enroll, manageable, available and active states" msgstr "" "Перенести узел между регистрацией, управляемым, доступным и активным " "состояниями" msgid "New Features" msgstr "Новые Свойства" msgid "Newton Series Release Notes" msgstr "Примечания к выпуску Newton Series " msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "" "Панель скрыта если baremetal сервис или права администратора отсутствуют" msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "В этот релиз входит поддержка добавления и удаления узлов. Также была " "реализована поддержка добавления и удаления портов. Панель теперь будет " "скрыта в случае отсутствия baremetal сервиса в сценарии где набор запущенных " "сервисов различается между различными регионами keystone. " msgid "" "This release adds support for editing nodes and moving those nodes between " "enroll, manageable, available and active states. It is now possible to " "enroll a node without all required fields for moving to manageable state " "being present due to the facility for editing the node once it has been " "created." msgstr "" "В релиз добавлена поддержка редактирования узлов и их перемещение между " "регистрацией, управляемым, доступным и активным состояниями. Теперь можно " "зарегистрировать узел без всех необходимых полей для перехода в управляемое " "состояние за счет возможности редактирования узла, как только он был создан." msgid "UX improvements across the interface" msgstr "UX улучшения интерфейса" ironic-ui-2.2.0/releasenotes/source/locale/id/0000775000567000056710000000000013046166505022404 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/id/LC_MESSAGES/0000775000567000056710000000000013046166505024171 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/id/LC_MESSAGES/releasenotes.po0000664000567000056710000000735413046166232027230 0ustar jenkinsjenkins00000000000000# suhartono , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-01-17 12:34+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-01-10 03:47+0000\n" "Last-Translator: suhartono \n" "Language-Team: Indonesian\n" "Language: id\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.0.0" msgstr "2.0.0" msgid "2.1.0" msgstr "2.1.0" msgid "Ability to enroll a node without all required fields for other states" msgstr "" "Kemampuan untuk mendaftar node tanpa semua field yang diperlukan untuk " "keadaan lainnya" msgid "Add and delete nodes" msgstr "Menambah dan menghapus node" msgid "Add and delete ports" msgstr "Menambah dan menghapus port" msgid "Breadcrumbs have been added" msgstr "Breadcrumbs telah ditambahkan" msgid "Current Series Release Notes" msgstr "Current Series Release Notes (catatan rilis seri saat ini)" msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "Saat ini tidak mungkin untuk mengedit node melalui UI setelah telah " "terdaftar. Oleh karena itu, pendaftaran harus dilakukan secara akurat untuk " "memastikan node terdaftar secara akurat dan kemudian dapat dibuat tersedia. " "Saat ini, setiap kesalahan yang dibuat saat pendaftaran hanya dapat " "dikoreksi dengan menghapus node dan mendaftarkan lagi." msgid "Edit nodes after creation" msgstr "Mengedit node setelah penciptaan" msgid "Ironic UI Release Notes" msgstr "Ironic UI Release Notes (catalan rilis Ironic UI)" msgid "Known Issues" msgstr "Masalah yang diikenal" msgid "Move nodes between enroll, manageable, available and active states" msgstr "" "Pindahkan node di antara keadaan yang dapat didaftar, dikelola, dan " "disediakan" msgid "New Features" msgstr "Fitur baru" msgid "Newton Series Release Notes" msgstr "Newton Series Release Notes (catatan rilis seri Newton)" msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "Panel tersembunyi jika layanan baremetal atau hak admin tidak hadir" msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "Rilis ini menambahkan dukungan untuk menambah dan menghapus node. Dukungan " "juga telah ditambahkan untuk menambah dan menghapus port. Panel sekarang " "akan disembunyikan jika layanan baremetal tidak hadir dalam skenario dimana " "koleksi menjalankan layanan berbeda antara beberapa keystone region." msgid "" "This release adds support for editing nodes and moving those nodes between " "enroll, manageable, available and active states. It is now possible to " "enroll a node without all required fields for moving to manageable state " "being present due to the facility for editing the node once it has been " "created." msgstr "" "Rilis ini menambahkan dukungan untuk mengedit node dan bergerak dimana node " "di antara keadaan didaftar, dikelola, tersedia dan aktif. Sekarang mungkin " "untuk mendaftar node tanpa semua field yang diperlukan untuk pindah ke " "keadaan terkelola sedang ada karena fasilitas untuk mengedit node telah " "dibuat." msgid "UX improvements across the interface" msgstr "Perbaikan UX di seluruh antarmuka" ironic-ui-2.2.0/releasenotes/source/locale/ko_KR/0000775000567000056710000000000013046166505023015 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/ko_KR/LC_MESSAGES/0000775000567000056710000000000013046166505024602 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po0000664000567000056710000000762413046166232027641 0ustar jenkinsjenkins00000000000000# Eunseop Shin , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-10-07 16:48+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-20 07:55+0000\n" "Last-Translator: Eunseop Shin \n" "Language-Team: Korean (South Korea)\n" "Language: ko-KR\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.0.0" msgstr "2.0.0" msgid "2.1.0" msgstr "2.1.0" msgid "Ability to enroll a node without all required fields for other states" msgstr "다른 상태를 위해 요구되는 모든 필드를 제외한 노드 등록 능력" msgid "Add and delete nodes" msgstr "노드 추가, 삭제" msgid "Add and delete ports" msgstr "포트 추가, 삭제" msgid "Breadcrumbs have been added" msgstr "Breadcrumbs가 추가되었습니다." msgid "Current Series Release Notes" msgstr "최신 시리즈에 대한 릴리즈 노트" msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "현재, 한번 등록된 노드를 UI를 통해 수정 하는것은 불가능합니다. 따라서 등록" "이 정확하게 등록되어 있는지 확인할 수 있도록 등록을 정확하게 수행해야 합니" "다. 현재, 등록과정에서 일어나는 모든 에러들은 노드를 제거 하고 다시 등록 하" "는 방법으로만 고칠 수 있습니다." msgid "Edit nodes after creation" msgstr "생성 이전에 노드 수정" msgid "Ironic UI Release Notes" msgstr "Ironic UI에 대한 릴리즈 노트" msgid "Known Issues" msgstr "알려진 이슈" msgid "Move nodes between enroll, manageable, available and active states" msgstr "" "노드의 수정과 등록, 관리가능, 사용가능 그리고 활성화 상태 사이에서 노드의 이" "동." msgid "New Features" msgstr "새로운 기능" msgid "Newton Series Release Notes" msgstr "Newton 시리즈에 대한 릴리즈 노트" msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "패널은 베어메탈 서비스 이거나 관지자의 권한이 없을때 숨겨집니다." msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "이번 릴리즈는 노드의 추가삭제에 관한 지원을 추가합니다. 또한 포트 추가삭제에 " "대한 지원도 포함합니다. 패널은 현재 베어메탈 서비스가 실행중인 서비스의 컬렉" "션이 다중 keystone영역에서 다르다는 시나리오에 존재하지 않을 때 숨겨집니다." msgid "" "This release adds support for editing nodes and moving those nodes between " "enroll, manageable, available and active states. It is now possible to " "enroll a node without all required fields for moving to manageable state " "being present due to the facility for editing the node once it has been " "created." msgstr "" "이번 릴리즈는 노드의 수정과 등록, 관리가능, 사용가능 그리고 활성화 상태 사이" "에서 노드의 이동에 대한 지원을 추가합니다. 현재 노드를 관리가능 상태로 옮기" "기 위해 요청된 모든 필드가 없어도 등록하는것이 가능합니다. 때문에 노드를 편집" "하기 위한 기능은 노드가 생성 됬을 때 한번만 가능합니다." msgid "UX improvements across the interface" msgstr "인터페이스 전반에 걸친 UX 향상" ironic-ui-2.2.0/releasenotes/source/locale/ja/0000775000567000056710000000000013046166505022402 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/ja/LC_MESSAGES/0000775000567000056710000000000013046166505024167 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/ja/LC_MESSAGES/releasenotes.po0000664000567000056710000001011613046166232027214 0ustar jenkinsjenkins00000000000000# Akihiro Motoki , 2016. #zanata # Shu Muto , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-01-20 10:38+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-01-25 08:17+0000\n" "Last-Translator: Shu Muto \n" "Language-Team: Japanese\n" "Language: ja\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.0.0" msgstr "2.0.0" msgid "2.1.0" msgstr "2.1.0" msgid "Ability to enroll a node without all required fields for other states" msgstr "他の状態のためのすべての必須フィールドなしでノードを登録する機能" msgid "Add and delete nodes" msgstr "ノードの追加と削除。" msgid "Add and delete ports" msgstr "ポートの追加と削除。" msgid "Breadcrumbs have been added" msgstr "パンくずリスト (breadcrumb) のサポートが追加されました。" msgid "Current Series Release Notes" msgstr "開発中バージョンのリリースノート" msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "現在、UI を介して登録されたノードを編集することはできません。 したがって、" "ノードが正確に登録され、利用可能になるように、登録を正確に行う必要がありま" "す。 現在、登録中に発生したエラーは、ノードを削除して再度登録することによって" "のみ訂正できます。" msgid "Edit nodes after creation" msgstr "ノード作成後の更新" msgid "Ironic UI Release Notes" msgstr "Ironic UI リリースノート" msgid "Known Issues" msgstr "既知の問題" msgid "Move nodes between enroll, manageable, available and active states" msgstr "登録、管理可能、使用可能、およびアクティブ状態の間でノードを移動する。" msgid "New Features" msgstr "新機能" msgid "Newton Series Release Notes" msgstr "Newton バージョンのリリースノート" msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "ベアメタルサービスまたは管理者権限がない場合はパネルが非表示になります" msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "このリリースでは、ノードの追加と削除がサポートされています。 ポートの追加およ" "び削除のサポートも追加されました。 実行中のサービスのコレクションが複数の " "Keystone リージョンで異なるシナリオでは、ベアメタルサービスが存在しない場合、" "パネルは非表示になります。" msgid "" "This release adds support for editing nodes and moving those nodes between " "enroll, manageable, available and active states. It is now possible to " "enroll a node without all required fields for moving to manageable state " "being present due to the facility for editing the node once it has been " "created." msgstr "" "このリリースでは、ノードの編集とそのノードの登録、管理、使用可能、およびアク" "ティブの状態の間で移動がサポートされています。 いったん作成されたノードを編集" "する機能のため、管理可能な状態に移行するのに、すべての必須フィールドなしで" "ノードを登録することが可能になりました。" msgid "UX improvements across the interface" msgstr "インターフェーズ全体のユーザーエクスペリエンスの改善" ironic-ui-2.2.0/releasenotes/source/locale/fr/0000775000567000056710000000000013046166505022417 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/fr/LC_MESSAGES/0000775000567000056710000000000013046166505024204 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po0000664000567000056710000000763013046166232027240 0ustar jenkinsjenkins00000000000000# Gérald LONLAS , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-10-07 16:48+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-24 09:15+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.0.0" msgstr "2.0.0" msgid "2.1.0" msgstr "2.1.0" msgid "Ability to enroll a node without all required fields for other states" msgstr "" "La possibilité d'enroller un nœud sans avoir tous les champs requis pour les " "autres états." msgid "Add and delete nodes" msgstr "Ajout et suppression des nœuds" msgid "Add and delete ports" msgstr "Ajout et suppression des ports" msgid "Breadcrumbs have been added" msgstr "Un fil d'ariane a été ajouté" msgid "Current Series Release Notes" msgstr "Note de la release actuelle" msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "Actuellement il est impossible d'éditer un nœud depuis l'interface graphique " "une fois qu'il a été enrollé. C'est pour cela que l'enrollement doit être " "fait avec précision afin d'assurer qu'un nœud est correctement enrollé et " "qu'il peut être disponible. À présent, si une erreur se produit durant " "l'enrollement, la seule façon de le corriger est de supprimer le nœud et de " "recommencer." msgid "Edit nodes after creation" msgstr "Éditer un nœud après sa création" msgid "Ironic UI Release Notes" msgstr "Note de release pour Ironic UI" msgid "Known Issues" msgstr "Problèmes connus" msgid "Move nodes between enroll, manageable, available and active states" msgstr "" "Déplacer les nœuds entre les états : \"enroll\", \"manageable\", \"available" "\" et \"active\"" msgid "New Features" msgstr "Nouvelles fonctionnalités" msgid "Newton Series Release Notes" msgstr "Note de release pour Newton" msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "" "Cache le panneau si le service Baremetal ou les droits admin ne sont pas " "présents." msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "Cette release ajoute le support de l'ajout et la suppression de nœud. Le " "support d'ajout et de suppression des ports a également été ajouté. La " "fenêtre sera maintenant cachée si le service baremetal n'est pas présent " "dans le scénario où la collection des services en cours diverge entre " "plusieurs région Keystone." msgid "" "This release adds support for editing nodes and moving those nodes between " "enroll, manageable, available and active states. It is now possible to " "enroll a node without all required fields for moving to manageable state " "being present due to the facility for editing the node once it has been " "created." msgstr "" "Cette release ajoute le support de l'édition des nœuds et permet le " "déplacement des nœuds entre les états : \"enroll\", \"manageable\", " "\"available\" et \"active\". Il est désormais possible d'enroller un nœud " "sans avoir tous les champs requis pour le déplacer à l'état \"manageable\" " "qui est présent dans la fonction d'édition du nœud une fois qu'il a été créé." msgid "UX improvements across the interface" msgstr "Améliorations UX sur toutes l'interface" ironic-ui-2.2.0/releasenotes/source/locale/zh_CN/0000775000567000056710000000000013046166505023011 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/zh_CN/LC_MESSAGES/0000775000567000056710000000000013046166505024576 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/releasenotes/source/locale/zh_CN/LC_MESSAGES/releasenotes.po0000664000567000056710000000454613046166232027635 0ustar jenkinsjenkins00000000000000# sunanchen , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-08-19 12:56+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-08-23 03:16+0000\n" "Last-Translator: sunanchen \n" "Language-Team: Chinese (China)\n" "Language: zh-CN\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "2.0.0" msgstr "2.0.0版本" msgid "Add and delete nodes" msgstr "增加或删除节点" msgid "Add and delete ports" msgstr "增加或删除端口" msgid "Breadcrumbs have been added" msgstr "已增加面包屑导航" msgid "Current Series Release Notes" msgstr "当前版本发布说明" msgid "" "Currently it is not possible to edit a node via the UI once it has been " "enrolled. Therefore, the enrollment must be done accurately to ensure the " "node is enrolled accurately and can then be made available. At present, any " "errors made during enrollment can only be corrected by deleting the node and " "enrolling it again." msgstr "" "目前,不支持通过UI修改已经注册的节点的信息。因此,请务必保证节点注册信息的精" "确性和可用性。目前,注册节点过程中出现的错误,只能通过删除节点之后重新注册来" "修正" msgid "Ironic UI Release Notes" msgstr "Ironic UI发布说明" msgid "Known Issues" msgstr "已知的问题" msgid "New Features" msgstr "新特性" msgid "Newton Series Release Notes" msgstr "Newton版本发布说明" msgid "Panel hidden if baremetal service or admin rights are not present" msgstr "如果当前baremetal service不可用或者admin权限不够,面板将会不可见" msgid "" "This release adds support for adding and deleting nodes. Support has also " "been added for adding and deleting ports. The panel will now be hidden if " "the baremetal service is not present in the scenario where the collection of " "running services differs between multiple keystone regions." msgstr "" "该版本支持增加和删除节点的功能。同样也支持增加和删除端口。在多keystone " "regions的情况下,如果当前场景下,baremetal service不可用,面板将会被隐藏" msgid "UX improvements across the interface" msgstr "通过修改接口的方式提升UX " ironic-ui-2.2.0/releasenotes/source/make.bat0000664000567000056710000001707213046166232022162 0ustar jenkinsjenkins00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. epub3 to make an epub3 echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled echo. coverage to run coverage check of the documentation if enabled echo. dummy to check syntax errors of document sources goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) REM Check if sphinx-build is available and fallback to Python version if any %SPHINXBUILD% 1>NUL 2>NUL if errorlevel 9009 goto sphinx_python goto sphinx_ok :sphinx_python set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) :sphinx_ok if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\ironic-ui.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\ironic-ui.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "epub3" ( %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "coverage" ( %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage if errorlevel 1 exit /b 1 echo. echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) if "%1" == "dummy" ( %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy if errorlevel 1 exit /b 1 echo. echo.Build finished. Dummy builder generates no files. goto end ) :end ironic-ui-2.2.0/releasenotes/source/Makefile0000664000567000056710000001670213046166232022214 0ustar jenkinsjenkins00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " epub3 to make an epub3" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" @echo " dummy to check syntax errors of document sources" .PHONY: clean clean: rm -rf $(BUILDDIR)/* .PHONY: html html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." .PHONY: dirhtml dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." .PHONY: singlehtml singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." .PHONY: pickle pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." .PHONY: json json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." .PHONY: htmlhelp htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." .PHONY: qthelp qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ironic-ui.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ironic-ui.qhc" .PHONY: applehelp applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." .PHONY: devhelp devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/ironic-ui" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ironic-ui" @echo "# devhelp" .PHONY: epub epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." .PHONY: epub3 epub3: $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 @echo @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." .PHONY: latex latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." .PHONY: latexpdf latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." .PHONY: latexpdfja latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." .PHONY: text text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." .PHONY: man man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." .PHONY: texinfo texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." .PHONY: info info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." .PHONY: gettext gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." .PHONY: changes changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." .PHONY: linkcheck linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." .PHONY: doctest doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." .PHONY: coverage coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." .PHONY: xml xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." .PHONY: pseudoxml pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." .PHONY: dummy dummy: $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy @echo @echo "Build finished. Dummy builder generates no files." ironic-ui-2.2.0/releasenotes/source/index.rst0000664000567000056710000000033413046166232022407 0ustar jenkinsjenkins00000000000000======================== Ironic UI Release Notes ======================== .. toctree:: :maxdepth: 1 Current (unreleased) Newton (unreleased) .. toctree:: :hidden: unreleased ironic-ui-2.2.0/releasenotes/source/unreleased.rst0000664000567000056710000000004013046166232023421 0ustar jenkinsjenkins00000000000000.. include:: current-series.rst ironic-ui-2.2.0/releasenotes/source/newton.rst0000664000567000056710000000020213046166232022604 0ustar jenkinsjenkins00000000000000=========================== Newton Series Release Notes =========================== .. release-notes:: :branch: origin/master ironic-ui-2.2.0/releasenotes/source/conf.py0000664000567000056710000002431313046166232022050 0ustar jenkinsjenkins00000000000000# -*- 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. # # ironic-ui documentation build configuration file, created by # sphinx-quickstart on Tue Aug 16 16:29:30 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. # # import os # import sys # 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', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] 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 = u'ironic-ui' copyright = u'2016, OpenStack' author = u'OpenStack' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = u'2.0.0' # The full version, including alpha/beta/rc tags. release = u'2.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. 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. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # 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 = 'sphinx' # 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 # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = 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 = 'default' # 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 = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. # " v documentation" by default. # # html_title = u'ironic-ui v2.0.0' # 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 (relative to this directory) to use as a 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 None, a 'Last updated on:' timestamp is inserted at every page # bottom, using the given strftime format. # The empty string is equivalent to '%b %d, %Y'. # # html_last_updated_fmt = None # 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 # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' # # html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # 'ja' uses this config value. # 'zh' user can custom change `jieba` dictionary path. # # html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. # # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = 'ironic-uidoc' # -- 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': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # 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 = [ (master_doc, 'ironic-ui.tex', u'ironic-ui Documentation', u'OpenStack', '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 = [] # It false, will not define \strong, \code, itleref, \crossref ... but only # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added # packages. # # latex_keep_old_macro_names = True # 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 = [ (master_doc, 'ironic-ui', u'ironic-ui Documentation', [author], 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 = [ (master_doc, 'ironic-ui', u'ironic-ui Documentation', author, 'ironic-ui', '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/'] ironic-ui-2.2.0/CONTRIBUTING.rst0000664000567000056710000000121513046166232017215 0ustar jenkinsjenkins00000000000000If you would like to contribute to the development of OpenStack, you must follow the steps in this page: http://docs.openstack.org/infra/manual/developers.html If you already have a good understanding of how the system works and your OpenStack accounts are set up, you can skip to the development workflow section of this documentation to learn how changes to OpenStack should be submitted for review via the Gerrit tool: http://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed on Launchpad, not GitHub: https://bugs.launchpad.net/ironic-ui ironic-ui-2.2.0/README.rst0000664000567000056710000000505313046166232016247 0ustar jenkinsjenkins00000000000000======================== Team and repository tags ======================== .. image:: http://governance.openstack.org/badges/ironic-ui.svg :target: http://governance.openstack.org/reference/tags/index.html .. Change things from this point on ========= Ironic UI ========= The Ironic UI is a Horizon plugin that will allow users to view and manage bare metal nodes, ports and drivers. * Free software: Apache license * Documentation: http://docs.openstack.org/developer/ironic-ui * Source: http://git.openstack.org/cgit/openstack/ironic-ui * Bugs: http://bugs.launchpad.net/ironic-ui Features -------- * View bare metal nodes * View node details * Apply maintenance and power on/off actions to the nodes Installation Instructions ------------------------- Please note that the following instructions assume that you have an existing installation of the OpenStack Horizon dashboard application. For Horizon installation please see http://docs.openstack.org/developer/horizon/quickstart.html 1. Clone the Ironic UI repository:: git clone https://git.openstack.org/openstack/ironic-ui 2. Change into the root directory of your horizon installation and activate the python virtual environment. Example:: source .venv/bin/activate .. NOTE:: The ``.venv`` folder is preinstalled when horizon is setup with ``./run_tests.sh``. Do not attempt to reinstall the virtual environment. 3. Copy the ``_2200_ironic.py`` file from ``ironic_ui/enabled/_2200_ironic.py`` file to ``horizon/openstack_dashboard/local/enabled`` directory. Example, set as if being executed from the root of the ironic-ui repository:: cp ./ironic_ui/enabled/_2200_ironic.py ../horizon/horizon/openstack_dashboard/local/enabled 4. Change into the ironic-ui repository and package the plugin:: pip install -e . This will build and install the ironic-ui plugin into the active virtual environment associated with your horizon installation. The plugin is installed in "editable" mode as a link back to your ironic-ui plugin directory. Also ensure that all packages as per requirements.txt have been installed. 5. Change back into the horizon repository and bring up your environment:: ./run_tests.sh --runserver The Ironic Bare Metal Provisioning plugin should now be visible in the Horizon navigation. Uninstallation -------------- To uninstall, use ``pip uninstall ironic-ui`` from with-in the horizon virtual environment. You will also need to remove the ``openstack_dashboard/enabled/_2200_ironic.py`` file from the horizon installation. ironic-ui-2.2.0/babel-djangojs.cfg0000664000567000056710000000110113046166232020071 0ustar jenkinsjenkins00000000000000[extractors] # We use a custom extractor to find translatable strings in AngularJS # templates. The extractor is included in horizon.utils for now. # See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for # details on how this works. angular = horizon.utils.babel_extract_angular:extract_angular [javascript: **.js] # We need to look into all static folders for HTML files. # The **/static ensures that we also search within # /openstack_dashboard/dashboards/XYZ/static which will ensure # that plugins are also translated. [angular: **/static/**.html] ironic-ui-2.2.0/requirements.txt0000664000567000056710000000042213046166232020037 0ustar jenkinsjenkins00000000000000# 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. pbr>=1.8 # Apache-2.0 python-ironicclient>=1.11.0 # Apache-2.0 ironic-ui-2.2.0/tox.ini0000664000567000056710000000337613046166232016101 0ustar jenkinsjenkins00000000000000[tox] minversion = 1.8 skipsdist = True envlist = py35,py34,py27,pep8 [testenv] usedevelop = True install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} setenv = VIRTUAL_ENV={envdir} NOSE_WITH_OPENSTACK=1 NOSE_OPENSTACK_COLOR=1 NOSE_OPENSTACK_RED=0.05 NOSE_OPENSTACK_YELLOW=0.025 NOSE_OPENSTACK_SHOW_ELAPSED=1 deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = {toxinidir}/manage.py test ironic_ui --settings=ironic_ui.test.settings [testenv:pep8] commands = flake8 {posargs} [testenv:venv] commands = {posargs} [testenv:cover] commands = python setup.py test --coverage --testr-args='{posargs}' [testenv:docs] commands = python setup.py build_sphinx [testenv:debug] commands = oslo_debug_helper {posargs} [flake8] show-source = True builtins = _ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build [testenv:releasenotes] commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [testenv:extractmessages] commands = pybabel extract -F babel-django.cfg \ -o ironic_ui/locale/django.pot -k gettext_noop -k gettext_lazy -k ngettext_lazy:1,2 \ -k ugettext_noop -k ugettext_lazy -k ungettext_lazy:1,2 -k npgettext:1c,2,3 \ -k pgettext_lazy:1c,2 -k npgettext_lazy:1c,2,3 --add-comments Translators: ironic_ui pybabel extract -F babel-djangojs.cfg \ -o ironic_ui/locale/djangojs.pot -k gettext_noop -k gettext_lazy -k ngettext_lazy:1,2 \ -k ugettext_noop -k ugettext_lazy -k ungettext_lazy:1,2 -k npgettext:1c,2,3 \ -k pgettext_lazy:1c,2 -k npgettext_lazy:1c,2,3 --add-comments Translators: ironic_ui ironic-ui-2.2.0/AUTHORS0000664000567000056710000000121113046166503015621 0ustar jenkinsjenkins00000000000000Aayush Rajoria Aayush Rajoria Andreas Jaeger Cao Xuan Hoang Deepak Doug Hellmann Elizabeth Elwell Flavio Percoco Julia Kreger Lucky samadhiya Peter Piela Rob Cresswell Thomas Goirand Tony Breeds Tony Xu Tyr Johanson Xu Ao gecong1973 ironic-ui-2.2.0/doc/0000775000567000056710000000000013046166505015325 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/doc/source/0000775000567000056710000000000013046166505016625 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/doc/source/installation.rst0000664000567000056710000000345313046166232022062 0ustar jenkinsjenkins00000000000000.. _installation: ====================== Ironic-UI Installation ====================== Please note that the following instructions assume that you have an existing installation of the OpenStack Horizon dashboard application. For Horizon installation please see http://docs.openstack.org/developer/horizon/quickstart.html 1. Clone the Ironic UI repository:: git clone https://git.openstack.org/openstack/ironic-ui 2. Change into the root directory of your horizon installation and activate the python virtualenv. Example:: source .venv/bin/activate .. NOTE:: The ``.venv`` folder is pre-installed when horizon is setup with ``./run_tests.sh``. Do not attempt to reinstall the virtual environment. 3. Copy the ``_2200_ironic.py`` file from ``ironic_ui/enabled/_2200_ironic.py`` file to ``horizon/openstack_dashboard/local/enabled`` directory. Example, set as if being executed from the root of the ironic-ui repository:: cp ./ironic_ui/enabled/_2200_ironic.py ../horizon/horizon/openstack_dashboard/local/enabled 4. Change into the ironic-ui repository and package the plugin:: pip install -r requirements.txt -e . This will build and install the ironic-ui plugin into the active virtual environment associated with your horizon installation. The plugin is installed in "editable" mode as a link back to your ironic-ui plugin directory. 5. Change back into the horizon repository and bring up your environment:: ./run_tests.sh --runserver The Bare Metal service should now be visible in the Horizon navigation. Uninstallation -------------- To uninstall, use ``pip uninstall ironic-ui`` from with-in the horizon virtual environment. You will also need to remove the ``openstack_dashboard/enabled/_2200_ironic.py`` file from the horizon installation. ironic-ui-2.2.0/doc/source/index.rst0000664000567000056710000000212413046166232020462 0ustar jenkinsjenkins00000000000000=============================================== Welcome to Ironic UI's developer documentation! =============================================== Introduction ============ The ironic UI is an OpenStack Horizon plugin that will allow users to view and manage their ironic bare metal nodes, ports and drivers. The documentation provided here is continually kept up-to-date based on the latest code that has been committed, and may not represent the state of the project at any specific prior release. For information on any current or prior version of Ironic, see `the release notes`_. .. _the release notes: http://docs.openstack.org/releasenotes/ironic-ui/ For more information on ironic, see `the ironic documentation`_. .. _the ironic documentation: http://docs.openstack.org/developer/ironic/ Administrator's Guide ===================== .. toctree:: :maxdepth: 1 Introduction to ironic Installing the ironic UI Contributing Release notes ironic-ui-2.2.0/doc/source/conf.py0000775000567000056710000000463113046166232020130 0ustar jenkinsjenkins00000000000000# -*- 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', 'oslosphinx' ] # 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 = u'ironic-ui' copyright = u'2016, 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 = 'sphinx' # -- 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 = '_theme' # html_static_path = ['static'] # Output file base name for HTML help builder. htmlhelp_basename = '%sdoc' % project # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass # [howto/manual]). latex_documents = [ ('index', '%s.tex' % project, u'%s Documentation' % project, u'OpenStack Foundation', 'manual'), ] # Example configuration for intersphinx: refer to the Python standard library. #intersphinx_mapping = {'http://docs.python.org/': None} ironic-ui-2.2.0/doc/source/contributing.rst0000664000567000056710000000215313046166232022064 0ustar jenkinsjenkins00000000000000.. _contributing: ========================= Contributing to Ironic UI ========================= If you're interested in contributing to the Ironic UI project, the following will help get you started. Contributor License Agreement ----------------------------- .. index:: single: license; agreement In order to contribute to the Ironic project, you need to have signed OpenStack's contributor's agreement. .. seealso:: * http://docs.openstack.org/infra/manual/developers.html * http://wiki.openstack.org/CLA LaunchPad Project ----------------- Most of the tools used for OpenStack depend on a launchpad.net ID for authentication. .. seealso:: * https://launchpad.net * https://launchpad.net/ironic Project Hosting Details ------------------------- Bug tracker http://launchpad.net/ironic-ui Mailing list (prefix subjects with ``[ironic-ui]`` for faster responses) http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev Code Hosting https://git.openstack.org/cgit/openstack/ironic-ui Code Review https://review.openstack.org/#/q/status:open+project:openstack/ironic-ui,n,z ironic-ui-2.2.0/setup.py0000664000567000056710000000200413046166232016263 0ustar jenkinsjenkins00000000000000# 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. # THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT import setuptools # In python < 2.7.4, a lazy loading of package `pbr` will break # setuptools if some other modules registered functions in `atexit`. # solution from: http://bugs.python.org/issue15881#msg170215 try: import multiprocessing # noqa except ImportError: pass setuptools.setup( setup_requires=['pbr>=1.8'], pbr=True) ironic-ui-2.2.0/test-requirements.txt0000664000567000056710000000124213046166232021015 0ustar jenkinsjenkins00000000000000# 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. # Require Horizon -e git://github.com/openstack/horizon.git#egg=horizon hacking<0.11,>=0.10.2 # Apache-2.0 coverage>=4.0 # Apache-2.0 django-nose>=1.4.4 # BSD python-subunit>=0.0.18 # Apache-2.0/BSD oslotest>=1.10.0 # Apache-2.0 testrepository>=0.0.18 # Apache-2.0/BSD testscenarios>=0.4 # Apache-2.0/BSD testtools>=1.4.0 # MIT # this is required for the docs build jobs sphinx!=1.3b1,<1.4,>=1.2.1 # BSD oslosphinx>=4.7.0 # Apache-2.0 reno>=1.8.0 # Apache-2.0 ironic-ui-2.2.0/setup.cfg0000664000567000056710000000174313046166505016406 0ustar jenkinsjenkins00000000000000[metadata] name = ironic-ui summary = Ironic plugin UI for Horizon to allow users to view and manage bare metal nodes, ports and drivers. description-file = README.rst author = OpenStack author-email = openstack-dev@lists.openstack.org home-page = http://docs.openstack.org/developer/ironic-ui 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 :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 [files] packages = ironic_ui [build_sphinx] source-dir = doc/source build-dir = doc/build all_files = 1 [upload_sphinx] upload-dir = doc/build/html [compile_catalog] directory = ironic_ui/locale domain = ironic-ui [egg_info] tag_build = tag_date = 0 ironic-ui-2.2.0/.coveragerc0000664000567000056710000000010613046166232016673 0ustar jenkinsjenkins00000000000000[run] branch = True source = ironic-ui [report] ignore_errors = True ironic-ui-2.2.0/ironic_ui.egg-info/0000775000567000056710000000000013046166505020232 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui.egg-info/dependency_links.txt0000664000567000056710000000000113046166503024276 0ustar jenkinsjenkins00000000000000 ironic-ui-2.2.0/ironic_ui.egg-info/top_level.txt0000664000567000056710000000001213046166503022753 0ustar jenkinsjenkins00000000000000ironic_ui ironic-ui-2.2.0/ironic_ui.egg-info/SOURCES.txt0000664000567000056710000001221013046166505022112 0ustar jenkinsjenkins00000000000000.coveragerc .eslintignore .eslintrc .mailmap .testr.conf AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE MANIFEST.in README.rst babel-django.cfg babel-djangojs.cfg manage.py package.json requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/source/conf.py doc/source/contributing.rst doc/source/index.rst doc/source/installation.rst ironic_ui/__init__.py ironic_ui.egg-info/PKG-INFO ironic_ui.egg-info/SOURCES.txt ironic_ui.egg-info/dependency_links.txt ironic_ui.egg-info/not-zip-safe ironic_ui.egg-info/pbr.json ironic_ui.egg-info/requires.txt ironic_ui.egg-info/top_level.txt ironic_ui/api/__init__.py ironic_ui/api/ironic.py ironic_ui/api/ironic_rest_api.py ironic_ui/content/__init__.py ironic_ui/content/ironic/__init__.py ironic_ui/content/ironic/panel.py ironic_ui/content/ironic/urls.py ironic_ui/content/ironic/views.py ironic_ui/content/ironic/templates/ironic/index.html ironic_ui/content/ironic/templates/ironic/node_detail.html ironic_ui/enabled/_2200_ironic.py ironic_ui/enabled/__init__.py ironic_ui/locale/de/LC_MESSAGES/django.po ironic_ui/locale/de/LC_MESSAGES/djangojs.po ironic_ui/locale/en_GB/LC_MESSAGES/django.po ironic_ui/locale/en_GB/LC_MESSAGES/djangojs.po ironic_ui/locale/fr/LC_MESSAGES/django.po ironic_ui/locale/fr/LC_MESSAGES/djangojs.po ironic_ui/locale/id/LC_MESSAGES/django.po ironic_ui/locale/id/LC_MESSAGES/djangojs.po ironic_ui/locale/ja/LC_MESSAGES/django.po ironic_ui/locale/ja/LC_MESSAGES/djangojs.po ironic_ui/locale/ko_KR/LC_MESSAGES/django.po ironic_ui/locale/ko_KR/LC_MESSAGES/djangojs.po ironic_ui/locale/ru/LC_MESSAGES/django.po ironic_ui/locale/ru/LC_MESSAGES/djangojs.po ironic_ui/locale/zh_CN/LC_MESSAGES/django.po ironic_ui/locale/zh_CN/LC_MESSAGES/djangojs.po ironic_ui/static/dashboard/admin/ironic/auto-focus.directive.js ironic_ui/static/dashboard/admin/ironic/empty-to-pristine.directive.js ironic_ui/static/dashboard/admin/ironic/ironic.module.js ironic_ui/static/dashboard/admin/ironic/ironic.service.js ironic_ui/static/dashboard/admin/ironic/modal-draggable.directive.js ironic_ui/static/dashboard/admin/ironic/node-actions.service.js ironic_ui/static/dashboard/admin/ironic/node-error.service.js ironic_ui/static/dashboard/admin/ironic/node-state-transition.service.js ironic_ui/static/dashboard/admin/ironic/update-patch.service.js ironic_ui/static/dashboard/admin/ironic/base-node/base-node.controller.js ironic_ui/static/dashboard/admin/ironic/base-node/base-node.html ironic_ui/static/dashboard/admin/ironic/base-node/base-node.service.js ironic_ui/static/dashboard/admin/ironic/base-node/base-node.spec.js ironic_ui/static/dashboard/admin/ironic/base-port/base-port.controller.js ironic_ui/static/dashboard/admin/ironic/base-port/base-port.html ironic_ui/static/dashboard/admin/ironic/create-port/create-port.controller.js ironic_ui/static/dashboard/admin/ironic/create-port/create-port.service.js ironic_ui/static/dashboard/admin/ironic/edit-node/edit-node.controller.js ironic_ui/static/dashboard/admin/ironic/edit-node/edit-node.service.js ironic_ui/static/dashboard/admin/ironic/edit-port/edit-port.controller.js ironic_ui/static/dashboard/admin/ironic/edit-port/edit-port.service.js ironic_ui/static/dashboard/admin/ironic/enroll-node/enroll-node.controller.js ironic_ui/static/dashboard/admin/ironic/enroll-node/enroll-node.service.js ironic_ui/static/dashboard/admin/ironic/maintenance/maintenance.controller.js ironic_ui/static/dashboard/admin/ironic/maintenance/maintenance.html ironic_ui/static/dashboard/admin/ironic/maintenance/maintenance.service.js ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.js ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.spec.js ironic_ui/static/dashboard/admin/ironic/node-details/node-details.html ironic_ui/static/dashboard/admin/ironic/node-details/sections/configuration.html ironic_ui/static/dashboard/admin/ironic/node-details/sections/overview.html ironic_ui/static/dashboard/admin/ironic/node-list/node-list.controller.js ironic_ui/static/dashboard/admin/ironic/node-list/node-list.html ironic_ui/test/__init__.py ironic_ui/test/settings.py ironic_ui/test/urls.py ironic_ui/test/tests/__init__.py ironic_ui/test/tests/registration.py releasenotes/notes/.placeholder releasenotes/notes/2.0-release-3d8acae7c8de429b.yaml releasenotes/notes/2.1.0-release-3391dfbcf087c883.yaml releasenotes/notes/bug-1648548-6e846a0c1e1574aa.yaml releasenotes/notes/bug-1648550-32e28cf2a401bb02.yaml releasenotes/notes/bug-1648557-462ebfdf39efee1f.yaml releasenotes/notes/bug-1648563-e2bc262985873122.yaml releasenotes/source/Makefile releasenotes/source/conf.py releasenotes/source/current-series.rst releasenotes/source/index.rst releasenotes/source/make.bat releasenotes/source/newton.rst releasenotes/source/unreleased.rst releasenotes/source/_static/.placeholder releasenotes/source/locale/de/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/ru/LC_MESSAGES/releasenotes.po releasenotes/source/locale/zh_CN/LC_MESSAGES/releasenotes.poironic-ui-2.2.0/ironic_ui.egg-info/pbr.json0000664000567000056710000000005613046166503021707 0ustar jenkinsjenkins00000000000000{"git_version": "73874c1", "is_release": true}ironic-ui-2.2.0/ironic_ui.egg-info/requires.txt0000664000567000056710000000004513046166503022627 0ustar jenkinsjenkins00000000000000pbr>=1.8 python-ironicclient>=1.11.0 ironic-ui-2.2.0/ironic_ui.egg-info/not-zip-safe0000664000567000056710000000000113046166472022463 0ustar jenkinsjenkins00000000000000 ironic-ui-2.2.0/ironic_ui.egg-info/PKG-INFO0000664000567000056710000001003513046166503021324 0ustar jenkinsjenkins00000000000000Metadata-Version: 1.1 Name: ironic-ui Version: 2.2.0 Summary: Ironic plugin UI for Horizon to allow users to view and manage bare metal nodes, ports and drivers. Home-page: http://docs.openstack.org/developer/ironic-ui Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description: ======================== Team and repository tags ======================== .. image:: http://governance.openstack.org/badges/ironic-ui.svg :target: http://governance.openstack.org/reference/tags/index.html .. Change things from this point on ========= Ironic UI ========= The Ironic UI is a Horizon plugin that will allow users to view and manage bare metal nodes, ports and drivers. * Free software: Apache license * Documentation: http://docs.openstack.org/developer/ironic-ui * Source: http://git.openstack.org/cgit/openstack/ironic-ui * Bugs: http://bugs.launchpad.net/ironic-ui Features -------- * View bare metal nodes * View node details * Apply maintenance and power on/off actions to the nodes Installation Instructions ------------------------- Please note that the following instructions assume that you have an existing installation of the OpenStack Horizon dashboard application. For Horizon installation please see http://docs.openstack.org/developer/horizon/quickstart.html 1. Clone the Ironic UI repository:: git clone https://git.openstack.org/openstack/ironic-ui 2. Change into the root directory of your horizon installation and activate the python virtual environment. Example:: source .venv/bin/activate .. NOTE:: The ``.venv`` folder is preinstalled when horizon is setup with ``./run_tests.sh``. Do not attempt to reinstall the virtual environment. 3. Copy the ``_2200_ironic.py`` file from ``ironic_ui/enabled/_2200_ironic.py`` file to ``horizon/openstack_dashboard/local/enabled`` directory. Example, set as if being executed from the root of the ironic-ui repository:: cp ./ironic_ui/enabled/_2200_ironic.py ../horizon/horizon/openstack_dashboard/local/enabled 4. Change into the ironic-ui repository and package the plugin:: pip install -e . This will build and install the ironic-ui plugin into the active virtual environment associated with your horizon installation. The plugin is installed in "editable" mode as a link back to your ironic-ui plugin directory. Also ensure that all packages as per requirements.txt have been installed. 5. Change back into the horizon repository and bring up your environment:: ./run_tests.sh --runserver The Ironic Bare Metal Provisioning plugin should now be visible in the Horizon navigation. Uninstallation -------------- To uninstall, use ``pip uninstall ironic-ui`` from with-in the horizon virtual environment. You will also need to remove the ``openstack_dashboard/enabled/_2200_ironic.py`` file from the horizon installation. 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 :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 ironic-ui-2.2.0/.eslintignore0000664000567000056710000000002113046166232017251 0ustar jenkinsjenkins00000000000000node_modules distironic-ui-2.2.0/.mailmap0000664000567000056710000000013113046166232016171 0ustar jenkinsjenkins00000000000000# Format is: # # ironic-ui-2.2.0/ironic_ui/0000775000567000056710000000000013046166505016540 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/__init__.py0000664000567000056710000000120013046166232020637 0ustar jenkinsjenkins00000000000000# 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( 'ironic-ui').version_string() ironic-ui-2.2.0/ironic_ui/test/0000775000567000056710000000000013046166505017517 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/test/__init__.py0000664000567000056710000000000013046166232021613 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/test/settings.py0000664000567000056710000000264513046166232021735 0ustar jenkinsjenkins00000000000000# Copyright 2016 Cisco Systems, Inc. # Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP # # 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. # Default to Horizons test settings to avoid any missing keys from horizon.test.settings import * # noqa from openstack_dashboard.test.settings import * # noqa # pop these keys to avoid log warnings about deprecation # update_dashboards will populate them anyway HORIZON_CONFIG.pop('dashboards', None) HORIZON_CONFIG.pop('default_dashboard', None) # Update the dashboards with ironic_ui import ironic_ui.enabled import openstack_dashboard.enabled from openstack_dashboard.utils import settings settings.update_dashboards( [ ironic_ui.enabled, openstack_dashboard.enabled, ], HORIZON_CONFIG, INSTALLED_APPS ) # Ensure any duplicate apps are removed after the update_dashboards call INSTALLED_APPS = list(set(INSTALLED_APPS)) ironic-ui-2.2.0/ironic_ui/test/tests/0000775000567000056710000000000013046166505020661 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/test/tests/__init__.py0000664000567000056710000000000013046166232022755 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/test/tests/registration.py0000664000567000056710000000201213046166232023735 0ustar jenkinsjenkins00000000000000# Copyright 2015 Cisco Systems, Inc. # Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP # # 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 horizon from ironic_ui.content.ironic import panel as i_panel from openstack_dashboard.test import helpers as test class RegistrationTests(test.TestCase): def test_registered(self): dashboard = horizon.get_dashboard('admin') panel = dashboard.get_panel('ironic') self.assertEqual(panel.__class__, i_panel.Ironic) ironic-ui-2.2.0/ironic_ui/test/urls.py0000664000567000056710000000135013046166232021052 0ustar jenkinsjenkins00000000000000# # 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.urls import include from django.conf.urls import url import openstack_dashboard.urls urlpatterns = [ url(r'', include(openstack_dashboard.urls)) ] ironic-ui-2.2.0/ironic_ui/api/0000775000567000056710000000000013046166505017311 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/api/__init__.py0000664000567000056710000000000013046166232021405 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/api/ironic_rest_api.py0000775000567000056710000001530313046166232023036 0ustar jenkinsjenkins00000000000000# # Copyright 2015, 2016 Hewlett Packard Enterprise Development Company LP # Copyright 2016 Cray 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.views import generic from ironic_ui.api import ironic from openstack_dashboard.api.rest import urls from openstack_dashboard.api.rest import utils as rest_utils @urls.register class Nodes(generic.View): url_regex = r'ironic/nodes/$' @rest_utils.ajax() def get(self, request): """Get the list of nodes. :param request: HTTP request. :return: nodes. """ items = ironic.node_list(request) return { 'items': [i.to_dict() for i in items], } @rest_utils.ajax(data_required=True) def post(self, request): """Create an Ironic node :param request: HTTP request """ params = request.DATA.get('node') return ironic.node_create(request, params) @rest_utils.ajax(data_required=True) def delete(self, request): """Delete an Ironic node from inventory :param request: HTTP request """ params = request.DATA.get('node') return ironic.node_delete(request, params) @urls.register class Node(generic.View): url_regex = r'ironic/nodes/(?P[0-9a-f-]+)$' @rest_utils.ajax() def get(self, request, node_id): """Get information on a specific node. :param request: HTTP request. :param node_id: Node id. :return: node. """ return ironic.node_get(request, node_id).to_dict() @rest_utils.ajax(data_required=True) def patch(self, request, node_id): """Update an Ironic node :param request: HTTP request :param node_uuid: Node uuid. """ patch = request.DATA.get('patch') return ironic.node_update(request, node_id, patch) @urls.register class Ports(generic.View): url_regex = r'ironic/ports/$' @rest_utils.ajax() def get(self, request): """Get the list of ports associated with a specified node. :param request: HTTP request :return: List of ports. """ node_id = request.GET.get('node_id') items = ironic.node_list_ports(request, node_id) return { 'items': [i.to_dict() for i in items], } @rest_utils.ajax(data_required=True) def post(self, request): """Create a network port :param request: HTTP request :return: Port """ port = request.DATA.get('port') return ironic.port_create(request, port).to_dict() @rest_utils.ajax(data_required=True) def delete(self, request): """Delete a network port :param request: HTTP request """ params = request.DATA.get('port_uuid') return ironic.port_delete(request, params) @urls.register class Port(generic.View): url_regex = r'ironic/ports/(?P[0-9a-f-]+)$' @rest_utils.ajax(data_required=True) def patch(self, request, port_id): """Update an Ironic port :param request: HTTP request :param port_id: Port id. """ patch = request.DATA.get('patch') return ironic.port_update(request, port_id, patch) @urls.register class StatesPower(generic.View): url_regex = r'ironic/nodes/(?P[0-9a-f-]+)/states/power$' @rest_utils.ajax(data_required=True) def patch(self, request, node_id): """Set the power state for a specified node. :param request: HTTP request. :param node_id: Node name or uuid :return: Return code """ state = request.DATA.get('state') return ironic.node_set_power_state(request, node_id, state) @urls.register class StatesProvision(generic.View): url_regex = r'ironic/nodes/(?P[0-9a-f-]+)/states/provision$' @rest_utils.ajax(data_required=True) def put(self, request, node_uuid): """Set the provision state for a specified node. :param request: HTTP request. :param node_id: Node uuid :return: Return code """ verb = request.DATA.get('verb') return ironic.node_set_provision_state(request, node_uuid, verb) @urls.register class Maintenance(generic.View): url_regex = r'ironic/nodes/(?P[0-9a-f-]+)/maintenance$' @rest_utils.ajax() def patch(self, request, node_id): """Put a specified node into maintetance state :param request: HTTP request. :param node_id: Node name or uuid :return: Return code """ maint_reason = request.DATA.get('maint_reason') return ironic.node_set_maintenance( request, node_id, 'on', maint_reason=maint_reason) @rest_utils.ajax() def delete(self, request, node_id): """Take a specified node out of the maintetance state :param request: HTTP request. :param node_id: Node name or uuid :return: Return code """ return ironic.node_set_maintenance(request, node_id, 'off') @urls.register class Validate(generic.View): url_regex = r'ironic/nodes/(?P[0-9a-f-]+)/validate$' @rest_utils.ajax() def get(self, request, node_id): """Validate a specified node :param request: HTTP request. :param node_id: Node name or uuid :return: Dictionary of interface statuses """ return ironic.node_validate(request, node_id) @urls.register class Drivers(generic.View): url_regex = r'ironic/drivers/$' @rest_utils.ajax() def get(self, request): """Get the list of drivers :param request: HTTP request :return: drivers """ items = ironic.driver_list(request) return { 'items': [i.to_dict() for i in items] } @urls.register class DriverProperties(generic.View): url_regex = r'ironic/drivers/(?P[0-9a-zA-Z_-]+)/properties$' @rest_utils.ajax() def get(self, request, driver_name): """Get the properties associated with a specified driver :param request: HTTP request :param driver_name: Driver name :return: Dictionary of properties """ return ironic.driver_properties(request, driver_name) ironic-ui-2.2.0/ironic_ui/api/ironic.py0000775000567000056710000001673313046166232021160 0ustar jenkinsjenkins00000000000000# # Copyright 2015, 2016 Hewlett Packard Enterprise Development Company LP # Copyright 2016 Cray 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 ironicclient import client from ironicclient.v1 import resource_fields as res_fields from horizon.utils.memoized import memoized # noqa from openstack_dashboard.api import base DEFAULT_IRONIC_API_VERSION = '1.19' DEFAULT_INSECURE = False DEFAULT_CACERT = None IRONIC_CLIENT_CLASS_NAME = 'baremetal' @memoized def ironicclient(request): """Returns a client connected to the Ironic backend. :param request: HTTP request. :return: Ironic client. """ insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', DEFAULT_INSECURE) cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', DEFAULT_CACERT) ironic_url = base.url_for(request, IRONIC_CLIENT_CLASS_NAME) return client.Client(1, ironic_url, os_ironic_api_version=DEFAULT_IRONIC_API_VERSION, project_id=request.user.project_id, token=request.user.token.id, insecure=insecure, cacert=cacert) def node_list(request): """Retrieve a list of nodes. :param request: HTTP request. :return: A list of nodes. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.list """ node_manager = ironicclient(request).node return node_manager.list(detail=True, limit=0) def node_get(request, node_id): """Retrieve a node. :param request: HTTP request. :param node_id: The UUID of the node. :return: node. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.get """ return ironicclient(request).node.get(node_id) def node_list_ports(request, node_id): """List all the ports on a given node. :param request: HTTP request. :param node_id: The UUID of the node. :return: A full list of ports. (limit=0) http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.list_ports """ return ironicclient(request).node.list_ports(node_id, limit=0, detail=True) def node_set_power_state(request, node_id, state): """Set power state for a given node. :param request: HTTP request. :param node_id: The UUID of the node. :param state: the power state to set. :return: node. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.set_power_state """ return ironicclient(request).node.set_power_state(node_id, state) def node_set_provision_state(request, node_uuid, state): """Set the target provision state for a given node. :param request: HTTP request. :param node_uuid: The UUID of the node. :param state: the target provision state to set. :return: node. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.set_provision_state """ return ironicclient(request).node.set_provision_state(node_uuid, state) def node_set_maintenance(request, node_id, state, maint_reason=None): """Set the maintenance mode on a given node. :param request: HTTP request. :param node_id: The UUID of the node. :param state: The maintenance state to set. :return: node. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.set_maintenance """ return ironicclient(request).node.set_maintenance( node_id, state, maint_reason=maint_reason) def node_create(request, params): """Create a node :param request: HTTP request. :param params: Dictionary of node parameters """ node_manager = ironicclient(request).node node = node_manager.create(**params) field_list = ['chassis_uuid', 'driver', 'driver_info', 'properties', 'extra', 'uuid', 'name'] return dict([(f, getattr(node, f, '')) for f in field_list]) def node_delete(request, node_id): """Delete a node from inventory. :param request: HTTP request. :param node_id: The UUID of the node. :return: node. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.delete """ return ironicclient(request).node.delete(node_id) def node_update(request, node_id, patch): """Update a specified node. :param request: HTTP request. :param node_id: The UUID of the node. :param patch: Sequence of update operations :return: node. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.update """ ironicclient(request).node.update(node_id, patch) def node_validate(request, node_id): """Validate a specified node. :param request: HTTP request. :param node_id: The id of the node. :return: Dictionary of interface statuses http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.node.html#ironicclient.v1.node.NodeManager.validate """ ifaces = ironicclient(request).node.validate(node_id) result = [] for interface, status in ifaces.to_dict().items(): data = {'interface': interface} data.update(status) result.append(data) return result def driver_list(request): """Retrieve a list of drivers. :param request: HTTP request. :return: A list of drivers. """ return ironicclient(request).driver.list() def driver_properties(request, driver_name): """Retrieve the properties of a specified driver :param request: HTTP request :param driver_name: Name of the driver :return: Property list """ return ironicclient(request).driver.properties(driver_name) def port_create(request, params): """Create network port :param request: HTTP request :param params: Port creation parameters :return: Port """ port_manager = ironicclient(request).port return port_manager.create(**params) def port_delete(request, port_uuid): """Delete a network port :param request: HTTP request :param port_uuid: Port uuid :return: Port """ return ironicclient(request).port.delete(port_uuid) def port_update(request, port_id, patch): """Update a specified port. :param request: HTTP request. :param node_id: The uuid of the port. :param patch: Sequence of update operations :return: port. http://docs.openstack.org/developer/python-ironicclient/api/ironicclient.v1.port.html#ironicclient.v1.port.PortManager.update """ port = ironicclient(request).port.update(port_id, patch) return dict([(f, getattr(port, f, '')) for f in res_fields.PORT_DETAILED_RESOURCE.fields]) ironic-ui-2.2.0/ironic_ui/locale/0000775000567000056710000000000013046166505017777 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/de/0000775000567000056710000000000013046166505020367 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/de/LC_MESSAGES/0000775000567000056710000000000013046166505022154 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/de/LC_MESSAGES/djangojs.po0000664000567000056710000002511313046166232024312 0ustar jenkinsjenkins00000000000000# Andreas Jaeger , 2016. #zanata # Frank Kloeker , 2016. #zanata # Robert Simai , 2016. #zanata # Andreas Jaeger , 2017. #zanata # Robert Simai , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 11:21+0000\n" "Last-Translator: Robert Simai \n" "Language-Team: German\n" "Language: de\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" #, python-format msgid "A request has been made to change the provisioning state of node %s" msgstr "" "Eine Anfrage wurde erstellt, um den Provisionierungszustand des Knotens %s " "zu ändern" msgid "A unique node name. Optional." msgstr "Ein eindeutiger Knotenname. Optional." msgid "Abort cleaning" msgstr "Bereinigung abbrechen" msgid "Actions" msgstr "Aktionen" #, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "" "Sind Sie sicher, dass Sie den Knoten \"%s\" löschen wollen? Diese Aktion " "kann nicht rückgängig gemacht werden." msgstr[1] "" "Sind Sie sicher, dass Sie die Knoten \"%s\" löschen wollen? Diese Aktion " "kann nicht rückgängig gemacht werden." #, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "" "Sind Sie sicher, dass Sie den Port \"%s\" löschen wollen? Diese Aktion kann " "nicht rückgängig gemacht werden." msgstr[1] "" "Sind Sie sicher, dass Sie die Ports \"%s\" löschen wollen? Diese Aktion kann " "nicht rückgängig gemacht werden." msgid "Cancel" msgstr "Abbrechen" msgid "Chassis ID" msgstr "Chassis-ID" msgid "Choose an Image" msgstr "Wählen Sie ein Abbild" msgid "Clean Step" msgstr "Bereinigungsschritt" msgid "Configuration" msgstr "Konfiguration" msgid "Console Enabled" msgstr "Konsole aktiviert" msgid "Create Port" msgstr "Port erstellen" msgid "Create port" msgstr "Port erstellen" msgid "Created At" msgstr "Erstellt am" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "Standard ist ([^\"\\. ]+|\"[^\"]+\")" msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "Knoten löschen" msgstr[1] "Knoten löschen" msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "Port löschen" msgstr[1] "Ports löschen" msgid "Delete node" msgstr "Knoten löschen" msgid "Delete nodes" msgstr "Knoten löschen" msgid "Delete ports" msgstr "Ports löschen" msgid "Deploy Kernel" msgstr "Kernel bereitstellen" msgid "Deploy Ramdisk" msgstr "Ramdisk bereitstellen" msgid "Driver" msgstr "Treiber" msgid "Driver Details" msgstr "Treiberdetails" msgid "Driver Info" msgstr "Treiberinformationen" msgid "Driver Validation" msgstr "Treibervalidierung" msgid "Edit" msgstr "Bearbeiten" msgid "Edit Node" msgstr "Knoten bearbeiten" msgid "Enroll Node" msgstr "Knoten ausrollen" msgid "Extra" msgstr "Extra" msgid "Extras" msgstr "Extras" msgid "General" msgstr "Allgemein" msgid "Image Source" msgstr "Abbildquelle" msgid "Inspect" msgstr "Inspizieren" msgid "Inspection Finished At" msgstr "Inspektion beenden um" msgid "Inspection Started At" msgstr "Inspektion gestartet um" msgid "Instance ID" msgstr "Instanz-ID" msgid "Instance Info" msgstr "Instanzinformation" msgid "Instance Name" msgstr "Instanzname" msgid "Interface" msgstr "Interface" msgid "Kernel" msgstr "Kernel" msgid "Last Error" msgstr "Letzter Fehler" msgid "MAC Address" msgstr "MAC-Adresse" msgid "MAC address" msgstr "MAC-Adresse" msgid "MAC address for this port. Required." msgstr "MAC-Adresse für diesen Port. Erforderlich." msgid "Maintenance" msgstr "Wartung" msgid "Maintenance Reason" msgstr "Grund der Wartung" msgid "Maintenance off" msgstr "Wartung ausschalten" msgid "Maintenance on" msgstr "Wartung einschalten" msgid "Move to" msgstr "Verschieben nach" msgid "Name" msgstr "Name" msgid "No Instance" msgstr "Keine Instanz" msgid "No maintenance reason given." msgstr "Kein Wartungsgrund angegeben." msgid "No network ports have been defined" msgstr "Es wurden keine Netzwerkports definiert" msgid "Node" msgstr "Knoten" #, python-format msgid "Node %s is already in maintenance mode." msgstr "Knoten %s ist schon im Wartungsmodus." #, python-format msgid "Node %s is not in maintenance mode." msgstr "Knoten %s ist nicht im Wartungsmodus" #, python-format msgid "Node %s is not powered off." msgstr "Knoten %s ist nicht ausgeschaltet." #, python-format msgid "Node %s is not powered on." msgstr "Knoten %s ist nicht eingeschaltet." msgid "Node Driver" msgstr "Knotentreiber" msgid "Node ID" msgstr "Knoten-ID" msgid "Node Info" msgstr "Knoteninformation" msgid "Node Name" msgstr "Knotenname" msgid "One of this, (.*) must be specified\\." msgstr "Einer von diesen, (.*) muss spezifiziert sein\\." msgid "Overview" msgstr "Übersicht" msgid "Port successfully created" msgstr "Port erfolgreich erstellt" msgid "Ports" msgstr "Ports" msgid "Power State" msgstr "Zustand" msgid "Power off" msgstr "Ausschalten" msgid "Power on" msgstr "Einschalten" msgid "Properties" msgstr "Eigenschaften" msgid "Property Name" msgstr "Eigenschaftname" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "" "Geben Sie einen Grund an, warum Sie den/die ausgewählten Knoten in den " "Wartungsmodus setzen (optional)" msgid "Provision State" msgstr "Bereitstellungszustand" msgid "Provisioning State" msgstr "Provisionierungszustand" msgid "Provisioning Status" msgstr "Provisionierungsstatus" msgid "Put Node(s) Into Maintenance Mode" msgstr "Knoten in Wartungsmodus setzen" msgid "Ramdisk" msgstr "Ramdisk" msgid "Reason" msgstr "Grund" msgid "Refresh" msgstr "Aktualisieren" msgid "Refresh page to see updated power status" msgstr "Aktualisiere Seite, um den Power Status zu sehen" msgid "Required" msgstr "Erforderlich" msgid "Reservation" msgstr "Reservierung" msgid "Root GB" msgstr "Root GB" msgid "SSH Address" msgstr "SSH Adresse" msgid "SSH Key Contents" msgstr "SSH Schlüsselinhalt" msgid "SSH Key File" msgstr "SSH Schlüsseldatei" msgid "SSH Password" msgstr "SSH Passwort" msgid "SSH Port" msgstr "SSH-Port" msgid "SSH Username" msgstr "SSH-Benutzername" msgid "SSH terminal port" msgstr "SSH Terminal Port" msgid "Select a Driver" msgstr "Wählen Sie einen Treiber" msgid "Submit" msgstr "Abschicken" #, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "Knoten \"%s\" erfolgreich gelöscht" msgstr[1] "Knoten \"%s\" erfolgreich gelöscht" #, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "Port \"%s\" erfolgreich gelöscht" msgstr[1] "Port \"%s\" erfolgreich gelöscht" #, python-format msgid "Successfully updated node %s" msgstr "Knoten %s erfolgreich aktualisiert" msgid "Target Power State" msgstr "Ziel Power-Zustand" msgid "Target Provision State" msgstr "Ziel Bereitstellungszustand" msgid "UUID" msgstr "UUID" msgid "Unable to create node update patch." msgstr "Knoten-Aktualisierungspatch kann nicht erstellt werden." #, python-format msgid "Unable to create node: %s" msgstr "Knoten kann nicht erstellt werden: %s" #, python-format msgid "Unable to create port: %s" msgstr "Port kann nicht erstellt werden: %s" #, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "Knoten \"%s\" kann nicht gelöscht werden" msgstr[1] "Knoten \"%s\" können nicht gelöscht werden" #, python-format msgid "Unable to delete node %s: %s" msgstr "Knoten kann nicht gelöscht werden: %s: %s" #, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "Port \"%s\" kann nicht gelöscht werden" msgstr[1] "Ports \"%s\" können nicht gelöscht werden" #, python-format msgid "Unable to delete port: %s" msgstr "Port kann nicht gelöscht werden: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "Konnte den Knoten nicht ausschalten: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "Konnte den Knoten nicht einschalten: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "Konnte den Ironic Knoten nicht in den Wartungsmodus setzen: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "Konnte den Wartungsmodus vom Ironic Knoten nicht löschen: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Ironic Treiber können nicht abgerufen werden: %s" #, python-format msgid "Unable to retrieve Ironic nodes. %s" msgstr "Konnte die Ironic Knoten nicht abrufen: %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "Treibereigenschaften können nicht abgerufen werden: %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Konnte die Ironic-Knotenports nicht abrufen: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "Konnte den Ironic-Knoten nicht abrufen: %s" #, python-format msgid "Unable to set node provision state: %s" msgstr "Kann Provisionierungszustand nicht setzen: %s" #, python-format msgid "Unable to update node %s: %s" msgstr "Knoten %s kann nicht aktualisiert werden: %s" #, python-format msgid "Unable to validate node %s: %s" msgstr "Knoten %s kann nicht validiert werden: %s" msgid "Update Node" msgstr "Knoten aktualisieren" msgid "Updated At" msgstr "Aktualisiert am" msgid "Valid" msgstr "Gültig" msgid "Virtualization Software" msgstr "Virtualisierungssoftware" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "Standard (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgid "{$ collection.addPrompt $}:" msgstr "{$ collection.addPrompt $}:" msgid "{$ collection.title $}" msgstr "{$ collection.title $}" msgid "{$ ctrl.modalTitle $}" msgstr "{$ ctrl.modalTitle $}" msgid "{$ ctrl.submitButtonTitle $}" msgstr "{$ ctrl.submitButtonTitle $}" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/de/LC_MESSAGES/django.po0000664000567000056710000000117613046166232023760 0ustar jenkinsjenkins00000000000000# Robert Simai , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev9\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-10-07 16:48+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-17 01:04+0000\n" "Last-Translator: Robert Simai \n" "Language-Team: German\n" "Language: de\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "Ironic Bare Metal Provisioning" msgstr "Ironic Bare Metal Provisionierung" ironic-ui-2.2.0/ironic_ui/locale/ru/0000775000567000056710000000000013046166505020425 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/ru/LC_MESSAGES/0000775000567000056710000000000013046166505022212 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/ru/LC_MESSAGES/djangojs.po0000664000567000056710000002620513046166232024353 0ustar jenkinsjenkins00000000000000# Ilya Alekseyev , 2015. #zanata # OpenStack Infra , 2015. #zanata # Alexander , 2016. #zanata # Andreas Jaeger , 2016. #zanata # Fedor Tarasenko , 2016. #zanata # Alexander , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 10:49+0000\n" "Last-Translator: Alexander \n" "Language-Team: Russian\n" "Language: ru\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" msgid " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr " ([^\" ]+|\"[^\"]+\") \\(По умолчанию\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" #, python-format msgid "A request has been made to change the provisioning state of node %s" msgstr "Запрос был создал для изменения состояния подготовки узла %s" msgid "A unique node name. Optional." msgstr "Уникальное имя узла. Необязательный параметр." msgid "Actions" msgstr "Действия" #, fuzzy, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "" "Вы действительно хотите удалить узел \"%s\"? Это действие не может быть " "отменено." msgstr[1] "" msgstr[2] "" #, fuzzy, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "" "Вы действительно хотите удалить порт \"%s\"? Это действие не может быть " "отменено." msgstr[1] "" msgstr[2] "" msgid "Cancel" msgstr "Отмена" msgid "Chassis ID" msgstr "ID устройства" msgid "Choose an Image" msgstr "Выберите образ" msgid "Configuration" msgstr "Конфигурация" msgid "Console Enabled" msgstr "Консоль активирована" msgid "Create Port" msgstr "Создать порт" msgid "Create port" msgstr "Создать порт" msgid "Created At" msgstr "Создано" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "По умолчанию ([^\"\\. ]+|\"[^\"]+\")" #, fuzzy msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "Удалить узел" msgstr[1] "" msgstr[2] "" #, fuzzy msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "Удалить порт" msgstr[1] "" msgstr[2] "" msgid "Delete node" msgstr "Удалить узел" msgid "Delete nodes" msgstr "Удалить узлы" msgid "Delete ports" msgstr "Удалить порты" msgid "Deploy Kernel" msgstr "Развернуть ядро" msgid "Deploy Ramdisk" msgstr "Развернуть Ramdisk" msgid "Driver" msgstr "Драйвер" msgid "Driver Details" msgstr "Детали дравера" msgid "Driver Info" msgstr "Информация о драйвере" msgid "Edit" msgstr "Редактировать" msgid "Edit Node" msgstr "Редактировать узел" msgid "Enroll Node" msgstr "Зарегистрировать узел" msgid "Extra" msgstr "Дополнительно" msgid "Extras" msgstr "Дополнительно" msgid "General" msgstr "Общее" msgid "Inspection Finished At" msgstr "Проверка закончилась в" msgid "Inspection Started At" msgstr "Проверка началась в" msgid "Instance ID" msgstr "ID инстанса" msgid "Instance Info" msgstr "Информация об инстансе" msgid "Instance Name" msgstr "Имя инстанса" msgid "Kernel" msgstr "Ядро" msgid "Last Error" msgstr "Последняя ошибка" msgid "MAC Address" msgstr "MAC адрес" msgid "MAC address" msgstr "MAC адрес" msgid "MAC address for this port. Required." msgstr "MAC адрес для этого порта. Обязательный параметр." msgid "Maintenance" msgstr "Техническое обслуживание" msgid "Maintenance Reason" msgstr "Причина технического обслуживания" msgid "Maintenance off" msgstr "Не в режиме обслуживания" msgid "Maintenance on" msgstr "В режиме обслуживания" msgid "Name" msgstr "Имя" msgid "No Instance" msgstr "Нет инстанса" msgid "No maintenance reason given." msgstr "Не указаны причины обслуживания." msgid "No network ports have been defined" msgstr "Сетевые порты не были заданы" msgid "Node" msgstr "Узел" #, python-format msgid "Node %s is already in maintenance mode." msgstr "Узел %s уже находится в режиме обслуживания." #, python-format msgid "Node %s is not in maintenance mode." msgstr "Узел %s не в режиме обслуживания." #, python-format msgid "Node %s is not powered off." msgstr "Узел %s не выключен." #, python-format msgid "Node %s is not powered on." msgstr "Узел %s не включен." msgid "Node Driver" msgstr "Драйвер узла" msgid "Node ID" msgstr "ID узла" msgid "Node Info" msgstr "Информация об узле" msgid "Node Name" msgstr "Имя узла" msgid "One of this, (.*) must be specified\\." msgstr "Один из этих, (.*) должен быть определен\\." msgid "Overview" msgstr "Обзор" msgid "Port successfully created" msgstr "Порт создан успешно" msgid "Ports" msgstr "Порты" msgid "Power State" msgstr "Состояние" msgid "Power off" msgstr "Выключить" msgid "Power on" msgstr "Включить" msgid "Properties" msgstr "Свойства" msgid "Property Name" msgstr "Имя свойства" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "" "Опишите причину по которой вы переводите выбранные узлы в режим обслуживания " "(необязательно)" msgid "Provision State" msgstr "Статус развертывания" msgid "Provisioning State" msgstr "Статус развертывания" msgid "Provisioning Status" msgstr "Статус развертывания" msgid "Put Node(s) Into Maintenance Mode" msgstr "Перевести узел (узлы) в режим обслуживания" msgid "Ramdisk" msgstr "Ramdisk" msgid "Refresh" msgstr "Обновить" msgid "Refresh page to see updated power status" msgstr "Обновите страницу чтобы увидеть обновленный статус питания" msgid "Required" msgstr "Обязательно" msgid "Reservation" msgstr "Резервация" msgid "SSH Port" msgstr "Порт SSH" msgid "SSH Username" msgstr "Имя пользователя SSH" msgid "Select a Driver" msgstr "Выберите драйвер" msgid "Submit" msgstr "Отправить" #, fuzzy, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "Узел \"%s\" успешно удален" msgstr[1] "" msgstr[2] "" #, fuzzy, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "Порт \"%s\" успешно удален" msgstr[1] "" msgstr[2] "" #, python-format msgid "Successfully updated node %s" msgstr "Узел %s успешно обновлен" msgid "Target Power State" msgstr "Целевое состояние" msgid "Target Provision State" msgstr "Целевой статус развертывания" msgid "UUID" msgstr "UUID" msgid "Unable to create node update patch." msgstr "Невозможно создать патч обновления узла." #, python-format msgid "Unable to create node: %s" msgstr "Невозможно создать узел: %s" #, python-format msgid "Unable to create port: %s" msgstr "Невозможно создать порт: %s" #, fuzzy, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "Невозможно удалить узел \"%s\"" msgstr[1] "" msgstr[2] "" #, python-format msgid "Unable to delete node %s: %s" msgstr "Невозможно удалить узел %s: %s" #, fuzzy, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "Невозможно удалить порт \"%s\"" msgstr[1] "" msgstr[2] "" #, python-format msgid "Unable to delete port: %s" msgstr "Невозможно удалить порт: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "Невозможно выключить узел: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "Невозможно включить узел: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "Невозможно перевести ноду Ironic в режим обслуживания: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "Невозможно вывести узел Ironic из режима обслуживания: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Невозможно получить драйвера Ironic: %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "Невозможно получить свойства драйвера: %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Невозможно получить порты узла Ironic: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "Невозможно получить узел Ironic: %s" #, python-format msgid "Unable to set node provision state: %s" msgstr "Не удается установить состояние подготовки узла: %s" #, python-format msgid "Unable to update node %s: %s" msgstr "Невозможно обновить узел %s: %s" msgid "Update Node" msgstr "Обновить узел" msgid "Updated At" msgstr "Обновлено" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "По умолчанию (?:value )? - ([^\"\\. ]+|\"[^\"]+\")" msgid "{$ collection.addPrompt $}:" msgstr "{$ collection.addPrompt $}:" msgid "{$ collection.title $}" msgstr "{$ collection.title $}" msgid "{$ ctrl.modalTitle $}" msgstr "{$ ctrl.modalTitle $}" msgid "{$ ctrl.submitButtonTitle $}" msgstr "{$ ctrl.submitButtonTitle $}" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/ru/LC_MESSAGES/django.po0000664000567000056710000000135513046166232024015 0ustar jenkinsjenkins00000000000000# Alexander , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev9\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-10-07 16:48+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-19 02:08+0000\n" "Last-Translator: Alexander \n" "Language-Team: Russian\n" "Language: ru\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" msgid "Ironic Bare Metal Provisioning" msgstr "Разворачивание на пустой системе - Ironic" ironic-ui-2.2.0/ironic_ui/locale/id/0000775000567000056710000000000013046166505020373 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/id/LC_MESSAGES/0000775000567000056710000000000013046166505022160 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/id/LC_MESSAGES/djangojs.po0000664000567000056710000002402213046166232024314 0ustar jenkinsjenkins00000000000000# OpenStack Infra , 2015. #zanata # Andreas Jaeger , 2016. #zanata # suhartono , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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 07:25+0000\n" "Last-Translator: suhartono \n" "Language-Team: Indonesian\n" "Language: id\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" #, python-format msgid "A request has been made to change the provisioning state of node %s" msgstr "Permintaan telah dibuat untuk mengubah keadaan provisioning node %s" msgid "A unique node name. Optional." msgstr "Nama node yang unik. Pilihan." msgid "Abort cleaning" msgstr "Membatalkan pembersihan" msgid "Actions" msgstr "Aksi" #, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "" "Apakah Anda yakin ingin menghapus node \"%s\"? Tindakan ini tidak bisa " "dibatalkan." #, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "" "Apakah Anda yakin ingin menghapus port \"%s\"? Tindakan ini tidak bisa " "dibatalkan." msgid "Cancel" msgstr "Batal" msgid "Chassis ID" msgstr "Chassis ID" msgid "Choose an Image" msgstr "Pilih Image" msgid "Clean Step" msgstr "Membersihkan langkah" msgid "Configuration" msgstr "Konfigurasi" msgid "Console Enabled" msgstr "Console Enabled (konsol diaktifkan)" msgid "Create Port" msgstr "Buat Port" msgid "Create port" msgstr "Buat port" msgid "Created At" msgstr "Created At" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "Defaults ke ([^\"\\. ]+|\"[^\"]+\")" msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "Delete Node (hapus node)" msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "Delete Port (hapus port)" msgid "Delete node" msgstr "Hapus node" msgid "Delete nodes" msgstr "Hapus node" msgid "Delete ports" msgstr "Hapus port" msgid "Deploy Kernel" msgstr "Deploy Kernel (mengerahkan kernel)" msgid "Deploy Ramdisk" msgstr "Deploy Ramdisk (mengerahkan ramdisk)" msgid "Driver" msgstr "Driver" msgid "Driver Details" msgstr "Driver Details (rincian driver)" msgid "Driver Info" msgstr "Driver Info" msgid "Driver Validation" msgstr "Driver Validation (validasi driver)" msgid "Edit" msgstr "Edit" msgid "Edit Node" msgstr "Edit Node" msgid "Enroll Node" msgstr "Enroll Node" msgid "Extra" msgstr "Extra" msgid "Extras" msgstr "Extras" msgid "General" msgstr "General (umum)" msgid "Image Source" msgstr "Image Source" msgid "Inspect" msgstr "Inspect (periksa)" msgid "Inspection Finished At" msgstr "Inspection Finished At (pemeriksaan selesai)" msgid "Inspection Started At" msgstr "Inspection Started At (pemeriksaan dimulai)" msgid "Instance ID" msgstr "ID Instances" msgid "Instance Info" msgstr "Instance Info (info instance)" msgid "Instance Name" msgstr "Nama Instance" msgid "Interface" msgstr "Interface (antarmuka)" msgid "Kernel" msgstr "Kernel" msgid "Last Error" msgstr "Last Error (kesalahan terakhir)" msgid "MAC Address" msgstr "MAC Address" msgid "MAC address" msgstr "MAC address" msgid "MAC address for this port. Required." msgstr "MAC address untuk port ini. Wajib." msgid "Maintenance" msgstr "Maintenance (pemeliharaan)" msgid "Maintenance Reason" msgstr "Maintenance Reason (alasan pemeliharaan)" msgid "Maintenance off" msgstr "Maintenance off" msgid "Maintenance on" msgstr "Maintenance on" msgid "Move to" msgstr "Move to (pindah ke)" msgid "Name" msgstr "Nama" msgid "No Instance" msgstr "Tak ada Instance" msgid "No maintenance reason given." msgstr "Tidak ada alasan pemeliharaan diberikan." msgid "No network ports have been defined" msgstr "Tidak ada port jaringan telah didefinisikan" msgid "Node" msgstr "Node (simpul)" #, python-format msgid "Node %s is already in maintenance mode." msgstr "Node %s sudah dalam modus pemeliharaan." #, python-format msgid "Node %s is not in maintenance mode." msgstr "Node %s tidak dalam modus pemeliharaan." #, python-format msgid "Node %s is not powered off." msgstr "Node %s tidak dimatikan." #, python-format msgid "Node %s is not powered on." msgstr "Node %s tidak dinyalakan." msgid "Node Driver" msgstr "Node Driver" msgid "Node ID" msgstr "Node ID" msgid "Node Info" msgstr "Node Info (info node)" msgid "Node Name" msgstr "Node Name (nama node)" msgid "One of this, (.*) must be specified\\." msgstr "One of this, (.*) must be specified\\." msgid "Overview" msgstr "Iktisar" msgid "Port successfully created" msgstr "Port berhasil dibuat" msgid "Ports" msgstr "Port-Port" msgid "Power State" msgstr "Power State" msgid "Power off" msgstr "Power off" msgid "Power on" msgstr "Power on" msgid "Properties" msgstr "Property (sifat)" msgid "Property Name" msgstr "Property Name (nama property)" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "" "Berikan alasan mengapa Anda menempatkan node yang dipilih ke dalam modus " "pemeliharaan (opsional)" msgid "Provision State" msgstr "Provision State (keadaan penyediaan)" msgid "Provisioning State" msgstr "Provisioning State" msgid "Provisioning Status" msgstr "Provisioning Status (status penyediaan)" msgid "Put Node(s) Into Maintenance Mode" msgstr "Letakan Node(s) dalam Maintenance Mode" msgid "Ramdisk" msgstr "Ramdisk" msgid "Reason" msgstr "Reason (alasan)" msgid "Refresh" msgstr "Refresh" msgid "Refresh page to see updated power status" msgstr "Refresh halaman untuk melihat status daya diperbarui" msgid "Required" msgstr "Wajib" msgid "Reservation" msgstr "Reservation" msgid "Root GB" msgstr "Root GB" msgid "SSH Address" msgstr "SSH Address" msgid "SSH Key Contents" msgstr "SSH Key Contents (konten kunci SSH)" msgid "SSH Key File" msgstr "SSH Key File (file kunci SSH)" msgid "SSH Password" msgstr "SSH Password (password SSH)" msgid "SSH Port" msgstr "SSH Port" msgid "SSH Username" msgstr "SSH Username " msgid "SSH terminal port" msgstr "SSH terminal port (port terminal SSH)" msgid "Select a Driver" msgstr "Pilih Driver" msgid "Submit" msgstr "Submit (menyampaikan)" #, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "Berhasil hapus node \"%s\"" #, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "Berhasil hapus port \"%s\"" #, python-format msgid "Successfully updated node %s" msgstr "Berhasil perbarui node %s" msgid "Target Power State" msgstr "Target Power State" msgid "Target Provision State" msgstr "Target Provision State (keadaab penyediaan sasaran)" msgid "UUID" msgstr "UUID" msgid "Unable to create node update patch." msgstr "Tidak dapat membuat node update patch." #, python-format msgid "Unable to create node: %s" msgstr "Tidak dapat membuat node: %s" #, python-format msgid "Unable to create port: %s" msgstr "Tidak dapat membuat port: %s" #, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "Tidak dapat menghapus node \"%s\"" #, python-format msgid "Unable to delete node %s: %s" msgstr "Tidak dapat menghapus node %s: %s" #, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "Tidak dapat hapus port \"%s\"" #, python-format msgid "Unable to delete port: %s" msgstr "Tidak dapat menghapus port: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "Tidak dapat daya mati pada node: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "Tidak dapat daya hidup pada node: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "Tidak dapat menempatkan Ironic node dalam modus pemeliharaan: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "Tidak dapat menghapus Ironic node dari modus pemeliharaan: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Tidak dapat mengambil Ironic driver: %s" #, python-format msgid "Unable to retrieve Ironic nodes. %s" msgstr "Tidak dapat mengambil node Ironis. %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "Tidak dapat mengambil driver property: %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Tidak dapat mengambil Ironic node port: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "Tidak dapat mengambil Ironic node: %s" #, python-format msgid "Unable to set node provision state: %s" msgstr "Tidak dapat mengatur keadaan provision node: %s" #, python-format msgid "Unable to update node %s: %s" msgstr "Tidak dapat memperbarui node %s: %s" #, python-format msgid "Unable to validate node %s: %s" msgstr "Tidak dapat memvalidasi node %s: %s" msgid "Update Node" msgstr "Update Node" msgid "Updated At" msgstr "Diperbarui pada" msgid "Valid" msgstr "Valid (sah)" msgid "Virtualization Software" msgstr "Virtualization Software (software virtualisasi)" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgid "{$ collection.addPrompt $}:" msgstr "{$ collection.addPrompt $}:" msgid "{$ collection.title $}" msgstr "{$ collection.title $}" msgid "{$ ctrl.modalTitle $}" msgstr "{$ ctrl.modalTitle $}" msgid "{$ ctrl.submitButtonTitle $}" msgstr "{$ ctrl.submitButtonTitle $}" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/id/LC_MESSAGES/django.po0000664000567000056710000000117113046166232023757 0ustar jenkinsjenkins00000000000000# suhartono , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev45\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-01-17 12:34+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-01-10 02:16+0000\n" "Last-Translator: suhartono \n" "Language-Team: Indonesian\n" "Language: id\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "Ironic Bare Metal Provisioning" msgstr "Ironic Bare Metal Provisioning" ironic-ui-2.2.0/ironic_ui/locale/ko_KR/0000775000567000056710000000000013046166505021004 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/ko_KR/LC_MESSAGES/0000775000567000056710000000000013046166505022571 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/ko_KR/LC_MESSAGES/djangojs.po0000664000567000056710000002471013046166232024731 0ustar jenkinsjenkins00000000000000# Andreas Jaeger , 2016. #zanata # Eunseop Shin , 2016. #zanata # HYUNGBAI PARK , 2016. #zanata # Ian Y. Choi , 2016. #zanata # Sungjin Kang , 2016. #zanata # ChungYoung Cho , 2017. #zanata # Ian Y. Choi , 2017. #zanata # Sungjin Kang , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 06:04+0000\n" "Last-Translator: Ian Y. Choi \n" "Language-Team: Korean (South Korea)\n" "Language: ko-KR\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" #, python-format msgid "A request has been made to change the provisioning state of node %s" msgstr "노드 %s의 프로비저닝 상태 변경을 위한 요청이 처리되었습니다." msgid "A unique node name. Optional." msgstr "단일한 노드 명칭. 선택사항." msgid "Abort cleaning" msgstr "클린업 취소" msgid "Actions" msgstr "작업" #, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "노드 \"%s\" 를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다." #, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "포트 \"%s\" 를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다." msgid "Cancel" msgstr "취소하기" msgid "Chassis ID" msgstr "Chassis ID" msgid "Choose an Image" msgstr "이미지 선택하기" msgid "Clean Step" msgstr "클린업 단계" msgid "Configuration" msgstr "구성" msgid "Console Enabled" msgstr "콘솔 활성화" msgid "Create Port" msgstr "포트 생성하기" msgid "Create port" msgstr "포트 생성하기" msgid "Created At" msgstr "생성 시점" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "노드 삭제" msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "포트 삭제" msgid "Delete node" msgstr "노드 삭제하기" msgid "Delete nodes" msgstr "노드들 삭제하기" msgid "Delete ports" msgstr "포트 삭제하기" msgid "Deploy Kernel" msgstr "커널 배치하기" msgid "Deploy Ramdisk" msgstr "램디스크 배치하기" msgid "Driver" msgstr "드라이버" msgid "Driver Details" msgstr "드라이버 세부사항" msgid "Driver Info" msgstr "드라이버 정보" msgid "Driver Validation" msgstr "드라이버 확인" msgid "Edit" msgstr "편집" msgid "Edit Node" msgstr "노드 편집" msgid "Enroll Node" msgstr "노드 등록하기" msgid "Extra" msgstr "Extra" msgid "Extras" msgstr "Extra" msgid "General" msgstr "일반" msgid "Image Source" msgstr "이미지 소스" msgid "Inspect" msgstr "검사" msgid "Inspection Finished At" msgstr "점검 종료시점" msgid "Inspection Started At" msgstr "점검 시작 시점" msgid "Instance ID" msgstr "인스턴스 ID" msgid "Instance Info" msgstr "인스턴스 정보" msgid "Instance Name" msgstr "인스턴스 이름" msgid "Interface" msgstr "인터페이스" msgid "Kernel" msgstr "커널" msgid "Last Error" msgstr "마지막 에러" msgid "MAC Address" msgstr "MAC 주소" msgid "MAC address" msgstr "MAC 주소" msgid "MAC address for this port. Required." msgstr "이 포트를 위한 MAC 주소. 필수항목." msgid "Maintenance" msgstr "유지보수" msgid "Maintenance Reason" msgstr "유지보수 사유" msgid "Maintenance off" msgstr "유지보수 꺼짐" msgid "Maintenance on" msgstr "유지보수 켜짐" msgid "Move to" msgstr "이동" msgid "Name" msgstr "이름" msgid "No Instance" msgstr "인스턴스 없음" msgid "No maintenance reason given." msgstr "유지보수 이유가 주어지지 않았습니다." msgid "No network ports have been defined" msgstr "네트워크 포트가 정의되지 않았습니다" msgid "Node" msgstr "노드" #, python-format msgid "Node %s is already in maintenance mode." msgstr "노드 %s는 이미 유지보수 모드입니다." #, python-format msgid "Node %s is not in maintenance mode." msgstr "노드 %s는 유지보수 모드에 있지 않습니다." #, python-format msgid "Node %s is not powered off." msgstr "노드 %s의 전원이 꺼지지 않았습니다." #, python-format msgid "Node %s is not powered on." msgstr "노드 %s의 전원이 켜지지 않았습니다." msgid "Node Driver" msgstr "노드 드라이버" msgid "Node ID" msgstr "노드 ID" msgid "Node Info" msgstr "노드 정보" msgid "Node Name" msgstr "노드 명칭" msgid "One of this, (.*) must be specified\\." msgstr "One of this, (.*) must be specified\\." msgid "Overview" msgstr "개요" msgid "Port successfully created" msgstr "포트가 성공적으로 생성됐습니다" msgid "Ports" msgstr "포트들" msgid "Power State" msgstr "전원 상태" msgid "Power off" msgstr "전원 꺼짐" msgid "Power on" msgstr "전원 켜짐" msgid "Properties" msgstr "속성" msgid "Property Name" msgstr "속성 명칭" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "선택된 노드를 유지보수 모드로 넣는지 사유를 제공합니다 (선택항목)" msgid "Provision State" msgstr "권한설정 상태" msgid "Provisioning State" msgstr "권한설정 상태" msgid "Provisioning Status" msgstr "권한설정 상태" msgid "Put Node(s) Into Maintenance Mode" msgstr "노드(들)을 유지보수 모드로 넣기" msgid "Ramdisk" msgstr "램디스크" msgid "Reason" msgstr "원인" msgid "Refresh" msgstr "갱신" msgid "Refresh page to see updated power status" msgstr "갱신된 전원 상태를 보기 위해 페이지 새로 고치기" msgid "Required" msgstr "필수항목" msgid "Reservation" msgstr "예약" msgid "Root GB" msgstr "루트 GB" msgid "SSH Address" msgstr "SSH주소" msgid "SSH Key Contents" msgstr "SSH 키콘텐츠" msgid "SSH Key File" msgstr "SSH Key File" msgid "SSH Password" msgstr "SSH 패스워드" msgid "SSH Port" msgstr "SSH 포트" msgid "SSH Username" msgstr "SSH Username" msgid "SSH terminal port" msgstr "SSH 터미널포트" msgid "Select a Driver" msgstr "드라이버 선택하기" msgid "Submit" msgstr "제출" #, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "노드 \"%s\" 를 성공적으로 삭제했습니다" #, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "포트 \"%s\" 를 성공적으로 삭제했습니다" #, python-format msgid "Successfully updated node %s" msgstr "노드 %s가 성공적으로 업데이트 됨." msgid "Target Power State" msgstr "대상 전원 상태" msgid "Target Provision State" msgstr "대상 권한설정 상태" msgid "UUID" msgstr "UUID" msgid "Unable to create node update patch." msgstr "노드 업데이트 패치를 만들수 없습니다." #, python-format msgid "Unable to create node: %s" msgstr "노드를 생성할 수 없습니다: %s" #, python-format msgid "Unable to create port: %s" msgstr "포트를 생성할 수 없습니다: %s" #, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "노드 \"%s\" 를 삭제할 수 없습니다" #, python-format msgid "Unable to delete node %s: %s" msgstr "노드 %s를 삭제할 수 없습니다: %s" #, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "포트를 삭제할 수 없습니다: %s" #, python-format msgid "Unable to delete port: %s" msgstr "포트를 삭제할 수 없습니다: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "노드의 전원을 끌 수 없습니다: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "노드의 전원을 켤 수 없습니다: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "유지보수 모드에서 Ironic 노드를 넣을 수 없습니다: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "유지보수 모드에서 Ironic 노드를 삭제할 수 없습니다: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Ironic 드라이버를 되찾을 수 없습니다: %s" #, python-format msgid "Unable to retrieve Ironic nodes. %s" msgstr "Ironic 노드를 가져올 수 없습니다: %s " #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "드라이버 속성을 되찾을 수 없습니다 : %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Ironic 노드 포트를 가져올 수 없습니다: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "해당 Ironic 노드를 가져올 수 없습니다: %s " #, python-format msgid "Unable to set node provision state: %s" msgstr "노드 공급 상태를 설정 할 수 없습니다: %s" #, python-format msgid "Unable to update node %s: %s" msgstr "노드 %s를 업데이트 할 수 없습니다: %s" #, python-format msgid "Unable to validate node %s: %s" msgstr "노드 %s를 검증할수 없습니다: %s" msgid "Update Node" msgstr "노드 업데이트" msgid "Updated At" msgstr "업데이트 시점" msgid "Valid" msgstr "유효" msgid "Virtualization Software" msgstr "가상화 소프트트웨어" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgid "{$ collection.addPrompt $}:" msgstr "{$ collection.addPrompt $}:" msgid "{$ collection.title $}" msgstr "{$ collection.title $}" msgid "{$ ctrl.modalTitle $}" msgstr "{$ ctrl.modalTitle $}" msgid "{$ ctrl.submitButtonTitle $}" msgstr "{$ ctrl.submitButtonTitle $}" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/ko_KR/LC_MESSAGES/django.po0000664000567000056710000000121013046166232024362 0ustar jenkinsjenkins00000000000000# Eunseop Shin , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev9\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-10-07 16:48+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-20 05:14+0000\n" "Last-Translator: Eunseop Shin \n" "Language-Team: Korean (South Korea)\n" "Language: ko-KR\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "Ironic Bare Metal Provisioning" msgstr "Ironic 베어메탈 프로비저닝" ironic-ui-2.2.0/ironic_ui/locale/en_GB/0000775000567000056710000000000013046166505020751 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/en_GB/LC_MESSAGES/0000775000567000056710000000000013046166505022536 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/en_GB/LC_MESSAGES/djangojs.po0000664000567000056710000001375113046166232024701 0ustar jenkinsjenkins00000000000000# OpenStack Infra , 2015. #zanata # Rob Cresswell , 2015. #zanata # Andi Chandler , 2016. #zanata # Andreas Jaeger , 2016. #zanata # Rob Cresswell , 2016. #zanata # Andi Chandler , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 10:49+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en-GB\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "A unique node name. Optional." msgstr "A unique node name. Optional." msgid "Actions" msgstr "Actions" #, fuzzy, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgstr[1] "" msgid "Cancel" msgstr "Cancel" msgid "Chassis ID" msgstr "Chassis ID" msgid "Choose an Image" msgstr "Choose an Image" msgid "Configuration" msgstr "Configuration" msgid "Console Enabled" msgstr "Console Enabled" msgid "Created At" msgstr "Created At" #, fuzzy msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "Delete Node" msgstr[1] "" msgid "Delete node" msgstr "Delete node" msgid "Delete nodes" msgstr "Delete nodes" msgid "Deploy Kernel" msgstr "Deploy Kernel" msgid "Deploy Ramdisk" msgstr "Deploy Ramdisk" msgid "Driver" msgstr "Driver" msgid "Driver Details" msgstr "Driver Details" msgid "Driver Info" msgstr "Driver Info" msgid "Enroll Node" msgstr "Enroll Node" msgid "Extra" msgstr "Extra" msgid "Extras" msgstr "Extras" msgid "General" msgstr "General" msgid "Inspection Finished At" msgstr "Inspection Finished At" msgid "Inspection Started At" msgstr "Inspection Started At" msgid "Instance ID" msgstr "Instance ID" msgid "Instance Info" msgstr "Instance Info" msgid "Instance Name" msgstr "Instance Name" msgid "Kernel" msgstr "Kernel" msgid "Last Error" msgstr "Last Error" msgid "Maintenance" msgstr "Maintenance" msgid "Maintenance Reason" msgstr "Maintenance Reason" msgid "Maintenance off" msgstr "Maintenance off" msgid "Maintenance on" msgstr "Maintenance on" msgid "Name" msgstr "Name" msgid "No Instance" msgstr "No Instance" msgid "No maintenance reason given." msgstr "No maintenance reason given." #, python-format msgid "Node %s is already in maintenance mode." msgstr "Node %s is already in maintenance mode." #, python-format msgid "Node %s is not in maintenance mode." msgstr "Node %s is not in maintenance mode." #, python-format msgid "Node %s is not powered off." msgstr "Node %s is not powered off." #, python-format msgid "Node %s is not powered on." msgstr "Node %s is not powered on." msgid "Node Driver" msgstr "Node Driver" msgid "Node ID" msgstr "Node ID" msgid "Node Info" msgstr "Node Info" msgid "Node Name" msgstr "Node Name" msgid "Overview" msgstr "Overview" msgid "Ports" msgstr "Ports" msgid "Power State" msgstr "Power State" msgid "Power off" msgstr "Power off" msgid "Power on" msgstr "Power on" msgid "Properties" msgstr "Properties" msgid "Property Name" msgstr "Property Name" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgid "Provision State" msgstr "Provision State" msgid "Provisioning State" msgstr "Provisioning State" msgid "Provisioning Status" msgstr "Provisioning Status" msgid "Put Node(s) Into Maintenance Mode" msgstr "Put Node(s) Into Maintenance Mode" msgid "Ramdisk" msgstr "Ramdisk" msgid "Refresh page to see updated power status" msgstr "Refresh page to see updated power status" msgid "Required" msgstr "Required" msgid "Reservation" msgstr "Reservation" msgid "SSH Port" msgstr "SSH Port" msgid "SSH Username" msgstr "SSH Username" msgid "Select a Driver" msgstr "Select a Driver" #, fuzzy, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "Successfully deleted node \"%s\"" msgstr[1] "" msgid "Target Power State" msgstr "Target Power State" msgid "Target Provision State" msgstr "Target Provision State" msgid "UUID" msgstr "UUID" #, python-format msgid "Unable to create node: %s" msgstr "Unable to create node: %s" #, fuzzy, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "Unable to delete node \"%s\"" msgstr[1] "" #, python-format msgid "Unable to delete node %s: %s" msgstr "Unable to delete node %s: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "Unable to power off the node: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "Unable to power on the node: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "Unable to put the Ironic node in maintenance mode: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "Unable to remove the Ironic node from maintenance mode: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Unable to retrieve Ironic drivers: %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "Unable to retrieve driver properties: %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Unable to retrieve the Ironic node ports: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "Unable to retrieve the Ironic node: %s" msgid "Updated At" msgstr "Updated At" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/en_GB/LC_MESSAGES/django.po0000664000567000056710000000121113046166232024330 0ustar jenkinsjenkins00000000000000# Andi Chandler , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 1.1.1.dev28\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-07-13 21:09+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-29 01:16+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en-GB\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "Ironic Bare Metal Provisioning" msgstr "Ironic Bare Metal Provisioning" ironic-ui-2.2.0/ironic_ui/locale/ja/0000775000567000056710000000000013046166505020371 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/ja/LC_MESSAGES/0000775000567000056710000000000013046166505022156 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/ja/LC_MESSAGES/djangojs.po0000664000567000056710000002541313046166232024317 0ustar jenkinsjenkins00000000000000# Akihiro Motoki , 2016. #zanata # Andreas Jaeger , 2016. #zanata # Shu Muto , 2016. #zanata # Yoshiki Eguchi , 2016. #zanata # Akihiro Motoki , 2017. #zanata # Shu Muto , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 10:49+0000\n" "Last-Translator: Shu Muto \n" "Language-Team: Japanese\n" "Language: ja\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr " ([^\" ]+|\"[^\"]+\") \\(デフォルト\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" #, python-format msgid "A request has been made to change the provisioning state of node %s" msgstr "ノード %s のプロビジョニング状態を変更するための要求が作成されました。" msgid "A unique node name. Optional." msgstr "一意のノード名。オプション。" msgid "Abort cleaning" msgstr "クリーニングの中止" msgid "Actions" msgstr "アクション" #, fuzzy, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "ノード「%s」 を削除してよろしいですか?この操作は取り消せません。" #, fuzzy, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "ポート「%s」 を削除してよろしいですか?この操作は取り消せません。" msgid "Cancel" msgstr "取り消し" msgid "Chassis ID" msgstr "シャーシ ID" msgid "Choose an Image" msgstr "イメージの選択" msgid "Clean Step" msgstr "クリーニングステップ" msgid "Configuration" msgstr "設定" msgid "Console Enabled" msgstr "コンソールの有効化" msgid "Create Port" msgstr "ポートの作成" msgid "Create port" msgstr "ポートの作成" msgid "Created At" msgstr "作成時刻" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "デフォルトを ([^\"\\. ]+|\"[^\"]+\") にします" #, fuzzy msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "ノードの削除" #, fuzzy msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "ポートの削除" msgid "Delete node" msgstr "ノードの削除" msgid "Delete nodes" msgstr "ノードの削除" msgid "Delete ports" msgstr "ポートの削除" msgid "Deploy Kernel" msgstr "カーネルのデプロイ" msgid "Deploy Ramdisk" msgstr "RAM ディスクのデプロイ" msgid "Driver" msgstr "ドライバー" msgid "Driver Details" msgstr "ドライバー詳細" msgid "Driver Info" msgstr "ドライバー情報" msgid "Driver Validation" msgstr "ドライバーの検証" msgid "Edit" msgstr "編集" msgid "Edit Node" msgstr "ノードの編集" msgid "Enroll Node" msgstr "ノードの登録" msgid "Extra" msgstr "拡張" msgid "Extras" msgstr "拡張" msgid "General" msgstr "一般" msgid "Image Source" msgstr "イメージソース" msgid "Inspect" msgstr "検査" msgid "Inspection Finished At" msgstr "検査終了時刻" msgid "Inspection Started At" msgstr "検査開始時刻" msgid "Instance ID" msgstr "インスタンス ID" msgid "Instance Info" msgstr "インスタンス情報" msgid "Instance Name" msgstr "インスタンス名" msgid "Interface" msgstr "インターフェース" msgid "Kernel" msgstr "カーネル" msgid "Last Error" msgstr "最後のエラー" msgid "MAC Address" msgstr "MAC アドレス" msgid "MAC address" msgstr "MAC アドレス" msgid "MAC address for this port. Required." msgstr "このポートの MAC アドレス。必須。" msgid "Maintenance" msgstr "メンテナンス" msgid "Maintenance Reason" msgstr "メンテナンスの理由" msgid "Maintenance off" msgstr "メンテナンスオフ" msgid "Maintenance on" msgstr "メンテナンスオン" msgid "Move to" msgstr "移動先" msgid "Name" msgstr "名前" msgid "No Instance" msgstr "インスタンスなし" msgid "No maintenance reason given." msgstr "メンテナンスの理由がありません。" msgid "No network ports have been defined" msgstr "ネットワークポートが定義されていません" msgid "Node" msgstr "ノード" #, python-format msgid "Node %s is already in maintenance mode." msgstr "ノード %s は既にメンテナンスモードです。" #, python-format msgid "Node %s is not in maintenance mode." msgstr "ノード %s はメンテナンスモードになっていません。" #, python-format msgid "Node %s is not powered off." msgstr "ノード %s の電源がオフになっていません。" #, python-format msgid "Node %s is not powered on." msgstr "ノード %s の電源がオンになっていません。" msgid "Node Driver" msgstr "ノードドライバー" msgid "Node ID" msgstr "ノード ID" msgid "Node Info" msgstr "ノード情報" msgid "Node Name" msgstr "ノード名" msgid "One of this, (.*) must be specified\\." msgstr "(.*) の1つを指定する必要があります。" msgid "Overview" msgstr "概要" msgid "Port successfully created" msgstr "ポートが正常に作成されました" msgid "Ports" msgstr "ポート" msgid "Power State" msgstr "電源状態" msgid "Power off" msgstr "電源オフ" msgid "Power on" msgstr "電源オン" msgid "Properties" msgstr "プロパティー" msgid "Property Name" msgstr "プロパティ名" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "" "選択したノードをメンテナンスモードにする理由を設定してください(オプション)" msgid "Provision State" msgstr "プロビジョニング状態" msgid "Provisioning State" msgstr "プロビジョニング状態" msgid "Provisioning Status" msgstr "プロビジョニング状態" msgid "Put Node(s) Into Maintenance Mode" msgstr "ノードをメンテナンスモードにします" msgid "Ramdisk" msgstr "RAM ディスク" msgid "Reason" msgstr "理由" msgid "Refresh" msgstr "最新表示" msgid "Refresh page to see updated power status" msgstr "電源状態を更新するにはページをリフレッシュしてください" msgid "Required" msgstr "必須" msgid "Reservation" msgstr "予約" msgid "Root GB" msgstr "ルートディスク (GB)" msgid "SSH Address" msgstr "SSH アドレス" msgid "SSH Key Contents" msgstr "SSH 鍵の内容" msgid "SSH Key File" msgstr "SSH 鍵ファイル" msgid "SSH Password" msgstr "SSH パスワード" msgid "SSH Port" msgstr "SSH ポート" msgid "SSH Username" msgstr "SSH ユーザー名" msgid "SSH terminal port" msgstr "SSH ターミナルのポート" msgid "Select a Driver" msgstr "ドライバーを選択してください" msgid "Submit" msgstr "送信" #, fuzzy, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "ノード「%s」を正常に削除しました" #, fuzzy, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "ポート \"%s\" を正常に削除しました" #, python-format msgid "Successfully updated node %s" msgstr "ノード %s の更新に成功しました" msgid "Target Power State" msgstr "ターゲット電源状態" msgid "Target Provision State" msgstr "ターゲットプロビジョニング状態" msgid "UUID" msgstr "UUID" msgid "Unable to create node update patch." msgstr "ノードを更新するパッチを作成できません。" #, python-format msgid "Unable to create node: %s" msgstr "ノードを作成できません: %s" #, python-format msgid "Unable to create port: %s" msgstr "ポートを作成できません: %s" #, fuzzy, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "ノード 「%s」を削除できません" #, python-format msgid "Unable to delete node %s: %s" msgstr "ノード %s を削除できません: %s" #, fuzzy, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "ポート \"%s\" を削除できません" #, python-format msgid "Unable to delete port: %s" msgstr "ポートを削除できません: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "ノードを電源OFFにできません: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "ノードを電源オンにできません: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "Ironic ノードをメンテナンスモードにできません: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "Ironic ノードをメンテナンスモードから削除できません: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Ironic ドライバーの一覧を取得できません: %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "ドライバープロパティーの一覧を取得できません: %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Ironic ノードのポート一覧を取得できません: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "Ironic ノードを取得できません: %s" #, python-format msgid "Unable to set node provision state: %s" msgstr "ノードのプロビジョニング状態を設定できませんでした: %s" #, python-format msgid "Unable to update node %s: %s" msgstr "ノード %s を更新できません: %s" #, python-format msgid "Unable to validate node %s: %s" msgstr "ノード %s を検証できません: %s" msgid "Update Node" msgstr "ノードの更新" msgid "Updated At" msgstr "最終更新" msgid "Valid" msgstr "有効" msgid "Virtualization Software" msgstr "仮想化ソフトウェア" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "(?:value )?のデフォルトは ([^\"\\. ]+|\"[^\"]+\") です" msgid "{$ collection.addPrompt $}:" msgstr "{$ collection.addPrompt $}:" msgid "{$ collection.title $}" msgstr "{$ collection.title $}" msgid "{$ ctrl.modalTitle $}" msgstr "{$ ctrl.modalTitle $}" msgid "{$ ctrl.submitButtonTitle $}" msgstr "{$ ctrl.submitButtonTitle $}" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/ja/LC_MESSAGES/django.po0000664000567000056710000000120513046166232023753 0ustar jenkinsjenkins00000000000000# Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 1.1.1.dev9\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-05-05 12:53+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-04-01 04:04+0000\n" "Last-Translator: Shu Muto \n" "Language-Team: Japanese\n" "Language: ja\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "Ironic Bare Metal Provisioning" msgstr "Ironic ベアメタルプロビジョニング" ironic-ui-2.2.0/ironic_ui/locale/fr/0000775000567000056710000000000013046166505020406 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/fr/LC_MESSAGES/0000775000567000056710000000000013046166505022173 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/fr/LC_MESSAGES/djangojs.po0000664000567000056710000002270013046166232024330 0ustar jenkinsjenkins00000000000000# Gael Rehault , 2015. #zanata # OpenStack Infra , 2015. #zanata # Andreas Jaeger , 2016. #zanata # Gérald LONLAS , 2016. #zanata # Martine Marin , 2016. #zanata # Nicolas Fournier , 2016. #zanata # Gérald LONLAS , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 10:49+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 " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" #, python-format msgid "A request has been made to change the provisioning state of node %s" msgstr "" "Une requête a été envoyé pour changer l'état du provisionnement du nœud %s" msgid "A unique node name. Optional." msgstr "Un nom de nœud unique. Optionnel." msgid "Actions" msgstr "Actions" #, fuzzy, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "" "Etes-vous certain de vouloir supprimer le nœud \"%s\" ? Cette action est " "irréversible." msgstr[1] "" #, fuzzy, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "" "Etes-vous certain de vouloir supprimer le port \"%s\" ? Cette action est " "irréversible." msgstr[1] "" msgid "Cancel" msgstr "Annuler" msgid "Chassis ID" msgstr "ID du chassis" msgid "Choose an Image" msgstr "Choisir une image" msgid "Configuration" msgstr "Configuration" msgid "Console Enabled" msgstr "Console Activée" msgid "Create Port" msgstr "Créer un port" msgid "Create port" msgstr "Créer le port" msgid "Created At" msgstr "Créé le" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "Par défaut ([^\"\\. ]+|\"[^\"]+\")" #, fuzzy msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "Supprimer le nœud" msgstr[1] "" #, fuzzy msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "Supprimer le port" msgstr[1] "" msgid "Delete node" msgstr "Supprimer le nœud" msgid "Delete nodes" msgstr "Supprimer les nœuds" msgid "Delete ports" msgstr "Supprimer les ports" msgid "Deploy Kernel" msgstr "Kernel de déploiement" msgid "Deploy Ramdisk" msgstr "Ramdisk de déploiement" msgid "Driver" msgstr "Pilote" msgid "Driver Details" msgstr "Détails du pilote" msgid "Driver Info" msgstr "Info du pilote" msgid "Edit" msgstr "Editer" msgid "Edit Node" msgstr "Editer le nœud" msgid "Enroll Node" msgstr "Enroller le nœud" msgid "Extra" msgstr "Extra" msgid "Extras" msgstr "Extras" msgid "General" msgstr "Général" msgid "Inspection Finished At" msgstr "Inspection terminée à" msgid "Inspection Started At" msgstr "Inspection démarrée à" msgid "Instance ID" msgstr "ID de l'instance" msgid "Instance Info" msgstr "Infos de l'instance" msgid "Instance Name" msgstr "Nom de l'instance" msgid "Kernel" msgstr "Noyau" msgid "Last Error" msgstr "Dernière Erreur" msgid "MAC Address" msgstr "Adresse MAC" msgid "MAC address" msgstr "Adresse MAC" msgid "MAC address for this port. Required." msgstr "Adresse MAC pour ce port. Requis." msgid "Maintenance" msgstr "Maintenance" msgid "Maintenance Reason" msgstr "Raison de la maintenance" msgid "Maintenance off" msgstr "Maintenance désactivée" msgid "Maintenance on" msgstr "Maintenance activée" msgid "Name" msgstr "Nom" msgid "No Instance" msgstr "Pas d'instance" msgid "No maintenance reason given." msgstr "Aucune raison de maintenance fournie." msgid "No network ports have been defined" msgstr "Aucun port réseau n'a été défini" msgid "Node" msgstr "Nœud" #, python-format msgid "Node %s is already in maintenance mode." msgstr "Le nœud %s est déjà en mode maintenance." #, python-format msgid "Node %s is not in maintenance mode." msgstr "Le nœud %s n'est pas en mode maintenance." #, python-format msgid "Node %s is not powered off." msgstr "Le nœud %s n'est pas éteint." #, python-format msgid "Node %s is not powered on." msgstr "Le nœud %s n'est pas allumé." msgid "Node Driver" msgstr "Pilote du nœud" msgid "Node ID" msgstr "ID du nœud" msgid "Node Info" msgstr "Info du nœud" msgid "Node Name" msgstr "Nom du nœud" msgid "One of this, (.*) must be specified\\." msgstr "Une des leurs (.*) doit être spécifié\\." msgid "Overview" msgstr "Vue d'ensemble" msgid "Port successfully created" msgstr "Port crée avec succès" msgid "Ports" msgstr "Ports" msgid "Power State" msgstr "État de l'alimentation" msgid "Power off" msgstr "Éteindre" msgid "Power on" msgstr "Allumer" msgid "Properties" msgstr "Propriétés" msgid "Property Name" msgstr "Nom de la propriété" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "" "Fournir une raison pour avoir mis le(s) nœud(s) sélectionné(s) en mode " "maintenance (optionnel)" msgid "Provision State" msgstr "État de déploiement" msgid "Provisioning State" msgstr "État de déploiement" msgid "Provisioning Status" msgstr "Statut de Déploiement" msgid "Put Node(s) Into Maintenance Mode" msgstr "Mettre le(s) nœud(s) en mode maintenance" msgid "Ramdisk" msgstr "Ramdisk" msgid "Refresh" msgstr "Rafraichir" msgid "Refresh page to see updated power status" msgstr "Rafraichir la page pour voir les statuts d'alimentation à jour" msgid "Required" msgstr "Obligatoire" msgid "Reservation" msgstr "Réservation" msgid "SSH Port" msgstr "Port SSH" msgid "SSH Username" msgstr "Utilisateur SSH" msgid "Select a Driver" msgstr "Sélectionner un pilote" msgid "Submit" msgstr "Envoyer" #, fuzzy, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "Suppression avec succès du nœud \"%s\" " msgstr[1] "" #, fuzzy, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "Suppression avec succès du port \"%s\" " msgstr[1] "" #, python-format msgid "Successfully updated node %s" msgstr "Mise à jour avec succès du nœud %s" msgid "Target Power State" msgstr "État de l'alimentation de la cible" msgid "Target Provision State" msgstr "État de déploiement de la cible" msgid "UUID" msgstr "UUID" msgid "Unable to create node update patch." msgstr "Impossible de créer le patch de mise à jour du nœud." #, python-format msgid "Unable to create node: %s" msgstr "Impossible de créer le nœud : %s" #, python-format msgid "Unable to create port: %s" msgstr "Impossible de créer le port : %s" #, fuzzy, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "Impossible de supprimer le nœud \"%s\"" msgstr[1] "" #, python-format msgid "Unable to delete node %s: %s" msgstr "Impossible de supprimer le nœud %s : %s" #, fuzzy, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "Impossible de supprimer le port \"%s\"" msgstr[1] "" #, python-format msgid "Unable to delete port: %s" msgstr "Impossible de supprimer le port : %s" #, python-format msgid "Unable to power off the node: %s" msgstr "Impossible d'éteindre le nœud : %s" #, python-format msgid "Unable to power on the node: %s" msgstr "Impossible d'allumer le nœud : %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "Impossible de mettre le nœud Ironic en maintenance : %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "Impossible d'enlever le nœud Ironic de la maintenance : %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "Impossible de récupérer les pilotes Ironic : %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "Impossible de récupérer les propriétés du pilote : %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "Impossible de récupérer les ports du nœud Ironic : %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "Impossible de récupérer le nœud Ironic : %s" #, python-format msgid "Unable to set node provision state: %s" msgstr "Impossible de configurer l'état du provisionnement : %s" #, python-format msgid "Unable to update node %s: %s" msgstr "Impossible de mettre à jour le nœud %s : %s" msgid "Update Node" msgstr "Mettre à jour le nœud" msgid "Updated At" msgstr "Mis à jour à" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgid "{$ collection.addPrompt $}:" msgstr "{$ collection.addPrompt $}:" msgid "{$ collection.title $}" msgstr "{$ collection.title $}" msgid "{$ ctrl.modalTitle $}" msgstr "{$ ctrl.modalTitle $}" msgid "{$ ctrl.submitButtonTitle $}" msgstr "{$ ctrl.submitButtonTitle $}" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/fr/LC_MESSAGES/django.po0000664000567000056710000000121613046166232023772 0ustar jenkinsjenkins00000000000000# Nicolas Fournier , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 1.1.1.dev9\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-05-05 12:53+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-04-30 05:13+0000\n" "Last-Translator: Nicolas Fournier \n" "Language-Team: French\n" "Language: fr\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" msgid "Ironic Bare Metal Provisioning" msgstr "Déploiement Bare Metal Ironic" ironic-ui-2.2.0/ironic_ui/locale/zh_CN/0000775000567000056710000000000013046166505021000 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/zh_CN/LC_MESSAGES/0000775000567000056710000000000013046166505022565 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/locale/zh_CN/LC_MESSAGES/djangojs.po0000664000567000056710000001716013046166232024726 0ustar jenkinsjenkins00000000000000# OpenStack Infra , 2015. #zanata # zhangjingwen , 2015. #zanata # Andreas Jaeger , 2016. #zanata # Shengjing Zhu , 2016. #zanata # sunanchen , 2016. #zanata # vuuv , 2016. #zanata # sunanchen , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 2.1.1.dev66\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2017-02-03 15:06+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-03 10:49+0000\n" "Last-Translator: sunanchen \n" "Language-Team: Chinese (China)\n" "Language: zh-CN\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid " ([^\" ]+|\"[^\"]+\") \\(Default\\)" msgstr "([^\" ]+|\"[^\"]+\") \\(Default标签\\)" msgid "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgstr "(?:[Oo]ne of )(?!this)((?:(?:\"[^\"]+\"|[^,\\. ]+)(?:, |\\.))+)" msgid "A unique node name. Optional." msgstr "独一无二的节点名称。可选。" msgid "Actions" msgstr "动作" #, fuzzy, python-format msgid "" "Are you sure you want to delete node \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete nodes \"%s\"? This action cannot be undone." msgstr[0] "你确认要删除节点\"%s\"嘛?此操作将不可恢复" #, fuzzy, python-format msgid "" "Are you sure you want to delete port \"%s\"? This action cannot be undone." msgid_plural "" "Are you sure you want to delete ports \"%s\"? This action cannot be undone." msgstr[0] "你确认要删除端口\"%s\"吗?本操作无法恢复" msgid "Cancel" msgstr "取消" msgid "Chassis ID" msgstr "机架ID" msgid "Choose an Image" msgstr "选择一个镜像" msgid "Configuration" msgstr "配置" msgid "Console Enabled" msgstr "允许控制台" msgid "Create Port" msgstr "创建端口" msgid "Create port" msgstr "创建端口" msgid "Created At" msgstr "创建于" msgid "Defaults to ([^\"\\. ]+|\"[^\"]+\")" msgstr "默认为 ([^\"\\. ]+|\"[^\"]+\")" #, fuzzy msgid "Delete Node" msgid_plural "Delete Nodes" msgstr[0] "删除节点" #, fuzzy msgid "Delete Port" msgid_plural "Delete Ports" msgstr[0] "删除端口" msgid "Delete node" msgstr "删除节点" msgid "Delete nodes" msgstr "删除多个节点" msgid "Delete ports" msgstr "删除端口" msgid "Deploy Kernel" msgstr "部署内核" msgid "Deploy Ramdisk" msgstr "部署虚拟内存盘" msgid "Driver" msgstr "驱动" msgid "Driver Details" msgstr "驱动详情" msgid "Driver Info" msgstr "驱动信息" msgid "Enroll Node" msgstr "注册节点" msgid "Extra" msgstr "额外信息" msgid "Extras" msgstr "额外信息" msgid "General" msgstr "概要信息" msgid "Inspection Finished At" msgstr "检查结束于" msgid "Inspection Started At" msgstr "检查开始于" msgid "Instance ID" msgstr "云主机ID" msgid "Instance Info" msgstr "实例信息" msgid "Instance Name" msgstr "实例名字" msgid "Kernel" msgstr "内核" msgid "Last Error" msgstr "最近的一次错误" msgid "MAC Address" msgstr "MAC地址" msgid "MAC address" msgstr "MAC地址" msgid "MAC address for this port. Required." msgstr "需要该端口的MAC地址" msgid "Maintenance" msgstr "维护" msgid "Maintenance Reason" msgstr "维护原因" msgid "Maintenance off" msgstr "退出维护模式" msgid "Maintenance on" msgstr "处于维护状态" msgid "Name" msgstr "名称" msgid "No Instance" msgstr "没有实例" msgid "No maintenance reason given." msgstr "缺少提供维护原因" msgid "No network ports have been defined" msgstr "未定义网络端口" #, python-format msgid "Node %s is already in maintenance mode." msgstr "节点\"%s\"已经处于维护模式" #, python-format msgid "Node %s is not in maintenance mode." msgstr "节点\"%s\"没有处于维护模式" #, python-format msgid "Node %s is not powered off." msgstr "节点\"%s\"电源没有关闭" #, python-format msgid "Node %s is not powered on." msgstr "节点\"%s\"电源没有开启" msgid "Node Driver" msgstr "节点驱动" msgid "Node ID" msgstr "节点ID" msgid "Node Info" msgstr "节点信息" msgid "Node Name" msgstr "节点名称" msgid "One of this, (.*) must be specified\\." msgstr "必须指定其中的一个 (.*)" msgid "Overview" msgstr "概览" msgid "Port successfully created" msgstr "端口创建成功" msgid "Ports" msgstr "端口" msgid "Power State" msgstr "电源状态" msgid "Power off" msgstr "关闭电源" msgid "Power on" msgstr "打开电源" msgid "Properties" msgstr "属性" msgid "Property Name" msgstr "属性名称" msgid "" "Provide a reason for why you are putting the selected node(s) into " "maintenance mode (optional)" msgstr "提供一个你为什么选择将节点置于维护模式的原因(可选)" msgid "Provision State" msgstr "配置状态" msgid "Provisioning State" msgstr "配置状态" msgid "Provisioning Status" msgstr "配置状态" msgid "Put Node(s) Into Maintenance Mode" msgstr "将节点置于维护模式" msgid "Ramdisk" msgstr "内存盘" msgid "Refresh page to see updated power status" msgstr "刷新页面来确认电源状态是否更新" msgid "Required" msgstr "必需的" msgid "Reservation" msgstr "预留" msgid "SSH Port" msgstr "SSH端口" msgid "SSH Username" msgstr "SSH用户名" msgid "Select a Driver" msgstr "选择一种驱动" #, fuzzy, python-format msgid "Successfully deleted node \"%s\"" msgid_plural "Successfully deleted nodes \"%s\"" msgstr[0] "成功删除节点\"%s\"" #, fuzzy, python-format msgid "Successfully deleted port \"%s\"" msgid_plural "Successfully deleted ports \"%s\"" msgstr[0] "删除端口\"%s\"成功" msgid "Target Power State" msgstr "标记电源状态" msgid "Target Provision State" msgstr "标记配置状态" msgid "UUID" msgstr "UUID" #, python-format msgid "Unable to create node: %s" msgstr "无法创建Ironic节点: %s" #, python-format msgid "Unable to create port: %s" msgstr "无法创建端口: %s" #, fuzzy, python-format msgid "Unable to delete node \"%s\"" msgid_plural "Unable to delete nodes \"%s\"" msgstr[0] "无法删除节点\"%s\"" #, python-format msgid "Unable to delete node %s: %s" msgstr "无法删除Ironic节点\"%s\": %s" #, fuzzy, python-format msgid "Unable to delete port \"%s\"" msgid_plural "Unable to delete portss \"%s\"" msgstr[0] "无法删除端口\"%s\"" #, python-format msgid "Unable to delete port: %s" msgstr "无法删除端口: %s" #, python-format msgid "Unable to power off the node: %s" msgstr "无法关闭节点电源: %s" #, python-format msgid "Unable to power on the node: %s" msgstr "无法启动节点电源: %s" #, python-format msgid "Unable to put the Ironic node in maintenance mode: %s" msgstr "无法将Ironic节点置于维护模式: %s" #, python-format msgid "Unable to remove the Ironic node from maintenance mode: %s" msgstr "无法将Ironic节点退出维护模式: %s" #, python-format msgid "Unable to retrieve Ironic drivers: %s" msgstr "无法获取Ironic驱动: %s" #, python-format msgid "Unable to retrieve driver properties: %s" msgstr "无法获取驱动属性: %s" #, python-format msgid "Unable to retrieve the Ironic node ports: %s" msgstr "无法获取Ironic节点端口信息: %s" #, python-format msgid "Unable to retrieve the Ironic node: %s" msgstr "无法获取Ironic节点信息: %s" msgid "Updated At" msgstr "已更新于" msgid "default (?:value )?is ([^\"\\. ]+|\"[^\"]+\")" msgstr "默认值 (?:value )?是 ([^\"\\. ]+|\"[^\"]+\")" msgid "{$ property.getDescription() $}" msgstr "{$ property.getDescription() $}" ironic-ui-2.2.0/ironic_ui/locale/zh_CN/LC_MESSAGES/django.po0000664000567000056710000000117613046166232024371 0ustar jenkinsjenkins00000000000000# Shengjing Zhu , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: ironic-ui 1.1.1.dev33\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-08-15 22:06+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-08-09 08:49+0000\n" "Last-Translator: Shengjing Zhu \n" "Language-Team: Chinese (China)\n" "Language: zh-CN\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "Ironic Bare Metal Provisioning" msgstr "裸金属 Ironic 配置向导" ironic-ui-2.2.0/ironic_ui/enabled/0000775000567000056710000000000013046166505020132 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/enabled/__init__.py0000664000567000056710000000000013046166232022226 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/enabled/_2200_ironic.py0000664000567000056710000000244713046166232022575 0ustar jenkinsjenkins00000000000000# Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP # Copyright (c) 2016 Cray 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 name of the panel to be added to HORIZON_CONFIG. Required. PANEL = 'ironic' # The name of the dashboard the PANEL associated with. Required. PANEL_DASHBOARD = 'admin' # The name of the panel group the PANEL is associated with. PANEL_GROUP = 'admin' # Python panel class of the PANEL to be added. ADD_PANEL = 'ironic_ui.content.ironic.panel.Ironic' # A list of applications to be prepended to INSTALLED_APPS ADD_INSTALLED_APPS = ['ironic_ui', ] # A list of AngularJS modules to be loaded when Angular bootstraps. ADD_ANGULAR_MODULES = ['horizon.dashboard.admin.ironic'] # Automatically discover static resources in installed apps AUTO_DISCOVER_STATIC_FILES = True ironic-ui-2.2.0/ironic_ui/content/0000775000567000056710000000000013046166505020212 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/content/__init__.py0000664000567000056710000000120013046166232022311 0ustar jenkinsjenkins00000000000000# 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( 'ironic-ui').version_string() ironic-ui-2.2.0/ironic_ui/content/ironic/0000775000567000056710000000000013046166505021475 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/content/ironic/templates/0000775000567000056710000000000013046166505023473 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/content/ironic/templates/ironic/0000775000567000056710000000000013046166505024756 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/content/ironic/templates/ironic/node_detail.html0000664000567000056710000000114013046166232030104 0ustar jenkinsjenkins00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Node Details" %}{% endblock %} {% block breadcrumb_nav %} {% endblock %} {% block page_header %} {% endblock %} {% block main %} {% endblock %} ironic-ui-2.2.0/ironic_ui/content/ironic/templates/ironic/index.html0000664000567000056710000000112613046166232026750 0ustar jenkinsjenkins00000000000000{% extends 'base.html' %} {% load i18n %} {% block title %}{% trans "Ironic Bare Metal Provisioning" %}{% endblock %} {% block breadcrumb_nav %} {% endblock %} {% block page_header %} {% endblock %} {% block main %} {% endblock %} ironic-ui-2.2.0/ironic_ui/content/ironic/__init__.py0000664000567000056710000000000013046166232023571 0ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/content/ironic/panel.py0000664000567000056710000000265313046166232023151 0ustar jenkinsjenkins00000000000000# Copyright 2016 Cisco Systems, Inc. # Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP # # 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 ugettext_lazy as _ import horizon from openstack_dashboard.api import base from openstack_dashboard.dashboards.admin import dashboard class Ironic(horizon.Panel): name = _("Ironic Bare Metal Provisioning") slug = 'ironic' permissions = ('openstack.roles.admin',) def allowed(self, context): request = context['request'] if not base.is_service_enabled(request, 'baremetal'): return False else: return super(Ironic, self).allowed(context) def nav(self, context): request = context['request'] if not base.is_service_enabled(request, 'baremetal'): return False else: return True dashboard.Admin.register(Ironic) ironic-ui-2.2.0/ironic_ui/content/ironic/views.py0000664000567000056710000000164013046166232023202 0ustar jenkinsjenkins00000000000000# Copyright 2016 Cisco Systems, Inc. # Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP # Copyright (c) 2016 Cray 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.views import generic class IndexView(generic.TemplateView): template_name = 'admin/ironic/index.html' class DetailView(generic.TemplateView): template_name = 'admin/ironic/node_detail.html' ironic-ui-2.2.0/ironic_ui/content/ironic/urls.py0000664000567000056710000000166313046166232023037 0ustar jenkinsjenkins00000000000000# Copyright 2016 Cisco Systems, Inc. # Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP # Copyright (c) 2016 Cray 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.urls import url import ironic_ui.api.ironic_rest_api # noqa from ironic_ui.content.ironic import views urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), url(r'^([^/]+)/$', views.DetailView.as_view(), name='detail'), ] ironic-ui-2.2.0/ironic_ui/static/0000775000567000056710000000000013046166505020027 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/0000775000567000056710000000000013046166505021756 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/0000775000567000056710000000000013046166505023046 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/0000775000567000056710000000000013046166505024331 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/edit-node/0000775000567000056710000000000013046166505026201 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/edit-node/edit-node.service.js0000664000567000056710000000247313046166232032051 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.edit-node.service', editNodeService); editNodeService.$inject = [ '$uibModal', 'horizon.dashboard.admin.ironic.basePath' ]; function editNodeService($uibModal, basePath) { var service = { modal: modal }; function modal(node) { var options = { controller: 'EditNodeController as ctrl', backdrop: 'static', resolve: { node: function() { return node; } }, templateUrl: basePath + '/base-node/base-node.html' }; return $uibModal.open(options); } return service; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/edit-node/edit-node.controller.js0000664000567000056710000001317613046166232032576 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; /** * Controller used to edit an existing Ironic node */ angular .module('horizon.dashboard.admin.ironic') .controller('EditNodeController', EditNodeController); EditNodeController.$inject = [ '$rootScope', '$controller', '$uibModalInstance', 'horizon.framework.widgets.toast.service', 'horizon.app.core.openstack-service-api.ironic', 'horizon.dashboard.admin.ironic.events', 'horizon.dashboard.admin.ironic.edit-node.service', 'horizon.dashboard.admin.ironic.update-patch.service', '$log', 'node' ]; function EditNodeController($rootScope, $controller, $uibModalInstance, toastService, ironic, ironicEvents, editNodeService, updatePatchService, $log, node) { var ctrl = this; $controller('BaseNodeController', {ctrl: ctrl, $uibModalInstance: $uibModalInstance}); ctrl.modalTitle = gettext("Edit Node"); ctrl.submitButtonTitle = gettext("Update Node"); ctrl.node.instance_info = {}; ctrl.baseNode = null; ctrl.propertyCollections.push({id: "instance_info", title: "Instance Info", addPrompt: "Add Instance Property", placeholder: "Instance Property Name"}); init(node); function init(node) { ctrl._loadDrivers().then(function() { _loadNodeData(node.uuid); }); ctrl._getImages(); } function _loadNodeData(nodeId) { ironic.getNode(nodeId).then(function(response) { var node = response.data; ctrl.baseNode = node; ctrl.node.name = node.name; for (var i = 0; i < ctrl.drivers.length; i++) { if (ctrl.drivers[i].name === node.driver) { ctrl.selectedDriver = ctrl.drivers[i]; break; } } ctrl.loadDriverProperties(node.driver).then(function() { angular.forEach(node.driver_info, function(value, property) { if (angular.isDefined(ctrl.driverProperties[property])) { ctrl.driverProperties[property].inputValue = value; } }); }); ctrl.node.properties = angular.copy(node.properties); ctrl.node.extra = angular.copy(node.extra); ctrl.node.instance_info = angular.copy(node.instance_info); ctrl.node.uuid = node.uuid; }); } /** * @description Construct a patch that converts source node into * target node * * @param {object} sourceNode - Source node * @param {object} targetNode - Target node * @return {object[]} Array of patch instructions */ function buildPatch(sourceNode, targetNode) { var patcher = new updatePatchService.UpdatePatch(); patcher.buildPatch(sourceNode.name, targetNode.name, "/name"); patcher.buildPatch(sourceNode.driver, targetNode.driver, "/driver"); patcher.buildPatch(sourceNode.properties, targetNode.properties, "/properties"); patcher.buildPatch(sourceNode.extra, targetNode.extra, "/extra"); patcher.buildPatch(sourceNode.driver_info, targetNode.driver_info, "/driver_info"); patcher.buildPatch(sourceNode.instance_info, targetNode.instance_info, "/instance_info"); return patcher.getPatch(); } ctrl.submit = function() { $uibModalInstance.close(); angular.forEach(ctrl.driverProperties, function(property, name) { $log.debug(name + ", required = " + property.isRequired() + ", active = " + property.isActive() + ", input-value = " + property.getInputValue() + ", default-value = " + property.getDefaultValue()); if (property.isActive() && property.getInputValue() && property.getInputValue() !== property.getDefaultValue()) { $log.debug("Setting driver property " + name + " to " + property.inputValue); ctrl.node.driver_info[name] = property.inputValue; } }); $log.info("Updating node " + JSON.stringify(ctrl.baseNode)); $log.info("to " + JSON.stringify(ctrl.node)); var patch = buildPatch(ctrl.baseNode, ctrl.node); $log.info("patch = " + JSON.stringify(patch.patch)); if (patch.status === updatePatchService.UpdatePatch.status.OK) { ironic.updateNode(ctrl.baseNode.uuid, patch.patch).then(function() { $rootScope.$emit(ironicEvents.EDIT_NODE_SUCCESS); }); } else { toastService.add('error', gettext('Unable to create node update patch.')); } }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-error.service.js0000664000567000056710000000467613046166232030414 0ustar jenkinsjenkins00000000000000/* * © Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .service('horizon.dashboard.admin.ironic.node-error.service', nodeErrorService); nodeErrorService.$inject = [ 'horizon.framework.widgets.toast.service' ]; function nodeErrorService(toastService) { // Node last_error cache indexed by node uuid var lastError = sessionStorage.nodeErrorService ? angular.fromJson(sessionStorage.nodeErrorService) : {}; /** * @description Get the error condition for a specified node * * @param {string} nodeUuid – node uuid * @return {string} Error condition */ this.getLastError = function(nodeUuid) { return angular.isDefined(lastError[nodeUuid]) ? lastError[nodeUuid] : null; }; /** * @description Store the error condition for a specified node * * @param {node} node – node * @return {void} */ function setLastError(node) { lastError[node.uuid] = node.last_error; // Store node error condition in browser session storage // which provides persistence across page transitions. sessionStorage.nodeErrorService = angular.toJson(lastError); } /** * @description Notify the user of a change in error condition for * specified node. * * @param {node} node – node being checked * @return {void} */ this.checkNodeError = function(node) { if (node.last_error !== null && node.last_error !== "" && (!angular.isDefined(lastError[node.uuid]) || node.last_error !== lastError[node.uuid])) { toastService.add( 'error', "Detected change in error condition on node " + node.name + ". " + node.last_error); } // Update stored node error condition setLastError(node); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/empty-to-pristine.directive.js0000664000567000056710000000205213046166232032251 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .directive('emptyToPristine', EmptyToPristine); function EmptyToPristine() { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attrs, ctrl) { ctrl.$parsers.push(function(viewValue) { if (viewValue === "") { ctrl.$setPristine(); } return viewValue; }); } }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/maintenance/0000775000567000056710000000000013046166505026613 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/maintenance/maintenance.service.js0000664000567000056710000000654513046166232033101 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray Inc. * Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP * * 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. */ (function() { 'use strict'; /* * @ngdoc service * @name horizon.dashboard.admin.ironic.maintenance.service * @description Service for putting nodes in, and removing them from * maintenance mode */ angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.maintenance.service', maintenanceService); maintenanceService.$inject = [ '$uibModal', 'horizon.dashboard.admin.ironic.basePath', 'horizon.dashboard.admin.ironic.actions' ]; function maintenanceService($uibModal, basePath, actions) { var service = { putNodeInMaintenanceMode: putNodeInMaintenanceMode, putNodesInMaintenanceMode: putNodesInMaintenanceMode, removeNodeFromMaintenanceMode: removeNodeFromMaintenanceMode, removeNodesFromMaintenanceMode: removeNodesFromMaintenanceMode }; return service; /* * @name horizon.dashboard.admin.ironic.maintenance.service. * putNodeInMaintenanceMode * @description Put a specified node in maintenance mode * @param {object} - Node * * @return {void} */ function putNodeInMaintenanceMode(node) { var options = { controller: "MaintenanceController as ctrl", templateUrl: basePath + '/maintenance/maintenance.html' }; $uibModal.open(options).result.then(function(maintReason) { actions.putNodeInMaintenanceMode(node, maintReason); }); } /* * @name horizon.dashboard.admin.ironic.maintenance.service. * putNodesInMaintenanceMode * @description Put the specified nodes in maintenance mode * @param {Array} - Nodes * * @return {void} */ function putNodesInMaintenanceMode(nodes) { var options = { controller: "MaintenanceController as ctrl", templateUrl: basePath + '/maintenance/maintenance.html' }; $uibModal.open(options).result.then(function(maintReason) { actions.putAllInMaintenanceMode(nodes, maintReason); }); } /* * @name horizon.dashboard.admin.ironic.maintenance.service. * removeNodeInMaintenanceMode * @description Remove a specified node from maintenance mode * @param {object} - Node * * @return {void} */ function removeNodeFromMaintenanceMode(node) { actions.removeNodeFromMaintenanceMode(node); } /* * @name horizon.dashboard.admin.ironic.maintenance.service. * removeNodesFromMaintenanceMode * @description Remove the specified nodes from maintenance mode * @param {Array} - Nodes * * @return {void} */ function removeNodesFromMaintenanceMode(nodes) { actions.removeAllFromMaintenanceMode(nodes); } } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/maintenance/maintenance.html0000664000567000056710000000165613046166232031770 0ustar jenkinsjenkins00000000000000 ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/maintenance/maintenance.controller.js0000664000567000056710000000262013046166232033612 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray Inc. * Copyright (c) 2016 Hewlett Packard Enterprise Development Company LP * * 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. */ (function() { 'use strict'; /** * @ngdoc controller * @name horizon.dashboard.admin.ironic:MaintenanceController * @ngController * * @description * Controller used to prompt the user for information associated with * putting one or more nodes into maintenance mode */ angular .module('horizon.dashboard.admin.ironic') .controller('MaintenanceController', MaintenanceController); MaintenanceController.$inject = [ '$uibModalInstance' ]; function MaintenanceController($uibModalInstance) { var ctrl = this; ctrl.cancel = function() { $uibModalInstance.dismiss('cancel'); }; ctrl.putInMaintenanceMode = function(maintReason) { $uibModalInstance.close(maintReason); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/create-port/0000775000567000056710000000000013046166505026556 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/create-port/create-port.service.js0000664000567000056710000000251313046166232032776 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.create-port.service', createPortService); createPortService.$inject = [ '$uibModal', 'horizon.dashboard.admin.ironic.basePath' ]; function createPortService($uibModal, basePath) { var service = { modal: modal }; return service; function modal(node) { var options = { controller: 'CreatePortController as ctrl', backdrop: 'static', resolve: { node: function() { return node; } }, templateUrl: basePath + '/base-port/base-port.html' }; return $uibModal.open(options).result; } } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/create-port/create-port.controller.js0000664000567000056710000000426413046166232033526 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; /** * Controller used to create a network port on a specified node */ angular .module('horizon.dashboard.admin.ironic') .controller('CreatePortController', CreatePortController); CreatePortController.$inject = [ '$rootScope', '$controller', '$uibModalInstance', 'horizon.app.core.openstack-service-api.ironic', 'horizon.dashboard.admin.ironic.events', 'node' ]; function CreatePortController($rootScope, $controller, $uibModalInstance, ironic, ironicEvents, node) { var ctrl = this; $controller('BasePortController', {ctrl: ctrl, $uibModalInstance: $uibModalInstance}); ctrl.modalTitle = gettext("Create Port"); ctrl.submitButtonTitle = ctrl.modalTitle; /** * Create the defined port * * @return {void} */ ctrl.createPort = function() { var port = angular.copy(ctrl.port); port.node_uuid = node.id; var attr = ctrl.localLinkConnection.$toPortAttr(); if (attr) { port.local_link_connection = attr; } if (ctrl.pxeEnabled.value !== 'True') { port.pxe_enabled = ctrl.pxeEnabled.value; } ironic.createPort(port).then( function(createdPort) { $rootScope.$emit(ironicEvents.CREATE_PORT_SUCCESS); $uibModalInstance.close(createdPort); }); }; ctrl.submit = function() { ctrl.createPort(); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-port/0000775000567000056710000000000013046166505026225 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-port/base-port.controller.js0000664000567000056710000001353013046166232032640 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; /** * Controller used to support operations on an Ironic port */ angular .module('horizon.dashboard.admin.ironic') .controller('BasePortController', BasePortController); BasePortController.$inject = [ '$uibModalInstance', 'horizon.dashboard.admin.ironic.validMacAddressPattern', 'horizon.dashboard.admin.ironic.validDatapathIdPattern', 'ctrl' ]; /** * Utility class for managing form fields * * @param {object} args - Valid properties are: * value - Initial value of the field * required - Does the field require a value * desc - Field description * pattern - Regular expression pattern used to match * valid input values * disabled - Is the field disabled * info - Additional information about the current state of * the field. It will be displayed in a tooltip associated * with the field. * * @return {void} */ function Field(args) { this.value = angular.isDefined(args.value) ? args.value : undefined; this.required = angular.isDefined(args.required) ? args.required : false; this.desc = angular.isDefined(args.desc) ? args.desc : undefined; this.pattern = angular.isDefined(args.pattern) ? new RegExp(args.pattern) : undefined; this.disabled = angular.isDefined(args.disabled) ? args.disabled : false; this.info = angular.isDefined(args.info) ? args.info : undefined; /** * Test whether the field has a non-empty value. Note that an * empty value can be either '' or undefined in the case of a * required field * * @return {boolean} Return true if the field has a value */ this.hasValue = function() { return angular.isDefined(this.value) && this.value !== ''; }; /** * Test whether the field has help-text * * @return {boolean} Return true if the field has help text */ this.hasHelpText = function() { return this.desc || this.info; }; /** * Get the help-text associated with this field * * @return {string} Return true if the field has help text */ this.getHelpText = function() { var text = angular.isDefined(this.desc) ? this.desc : ''; if (angular.isDefined(this.info)) { if (text !== '') { text += '

'; } text += this.info; } return text; }; } function BasePortController($uibModalInstance, validMacAddressPattern, validDatapathIdPattern, ctrl) { ctrl.port = { address: null, extra: {} }; ctrl.pxeEnabled = new Field({value: 'True'}); // Object used to manage local-link-connection form fields ctrl.localLinkConnection = { port_id: new Field({}), switch_id: new Field({ desc: gettext("MAC address or OpenFlow datapath ID"), pattern: validMacAddressPattern + '|' + validDatapathIdPattern}), switch_info: new Field({}), /** * Update the required property of each field based on current values * * @return {void} */ $update: function() { var required = this.port_id.hasValue() || this.switch_id.hasValue(); this.port_id.required = required; this.switch_id.required = required; }, /** * Generate an attribute object that conforms to the format * required for port creation using the Ironic client * * @return {object} local_link_connection attribute object. * A value of null is returned if the local-link-connection * information is incomplete. */ $toPortAttr: function() { var attr = {}; if (this.port_id.hasValue() && this.switch_id.hasValue()) { attr.port_id = this.port_id.value; attr.switch_id = this.switch_id.value; if (this.switch_info.hasValue()) { attr.switch_info = this.switch_info.value; } } return attr; }, /** * dis/enable the local-link-connection form fields * * @param {boolean} disabled - True if the local-link-connection form * fields should be disabled * @param {string} reason - Optional reason for the state change * @return {void} */ $setDisabled: function(disabled, reason) { angular.forEach(this, function(item) { if (item instanceof Field) { item.disabled = disabled; item.info = reason; } }); } }; /** * Cancel the modal * * @return {void} */ ctrl.cancel = function() { $uibModalInstance.dismiss('cancel'); }; /** * Delete a port metadata property * * @param {string} propertyName - Name of the property * @return {void} */ ctrl.deleteExtra = function(propertyName) { delete ctrl.port.extra[propertyName]; }; /** * Check whether the specified port metadata property already exists * * @param {string} propertyName - Name of the metadata property * @return {boolean} True if the property already exists, * otherwise false */ ctrl.checkExtraUnique = function(propertyName) { return !(propertyName in ctrl.port.extra); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-port/base-port.html0000664000567000056710000001267713046166232031021 0ustar jenkinsjenkins00000000000000 ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/ironic.service.js0000775000567000056710000003731713046166232027624 0ustar jenkinsjenkins00000000000000/* * © Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP * © Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.app.core.openstack-service-api') .factory('horizon.app.core.openstack-service-api.ironic', ironicAPI); ironicAPI.$inject = [ '$q', 'horizon.framework.util.http.service', 'horizon.framework.widgets.toast.service', 'horizon.dashboard.admin.ironic.node-error.service' ]; /** * @description Service that provides access to the Ironic client API * * @param {object} $q - Promise provider * @param {object} apiService - HTTP service * @param {object} toastService - User message service * @param {object} nodeErrorService - Node error service * @return {object} Ironic API service */ function ironicAPI($q, apiService, toastService, nodeErrorService) { var service = { createNode: createNode, createPort: createPort, deleteNode: deleteNode, deletePort: deletePort, getDrivers: getDrivers, getDriverProperties: getDriverProperties, getNode: getNode, getNodes: getNodes, getPortsWithNode: getPortsWithNode, powerOffNode: powerOffNode, powerOnNode: powerOnNode, putNodeInMaintenanceMode: putNodeInMaintenanceMode, removeNodeFromMaintenanceMode: removeNodeFromMaintenanceMode, setNodeProvisionState: setNodeProvisionState, updateNode: updateNode, updatePort: updatePort, validateNode: validateNode }; return service; /** * @description Retrieve a list of nodes * http://docs.openstack.org/developer/ironic/webapi/v1.html#get--v1-nodes * * @return {promise} Node collection in JSON * http://docs.openstack.org/developer/ironic/webapi/v1.html#NodeCollection */ function getNodes() { return apiService.get('/api/ironic/nodes/') .then(function(response) { angular.forEach(response.data.items, function(node) { nodeErrorService.checkNodeError(node); }); return response; }) .catch(function(response) { var msg = interpolate( gettext('Unable to retrieve Ironic nodes. %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Retrieve information about the given node. * * http://docs.openstack.org/developer/ironic/webapi/v1.html#get--v1- * nodes-(node_ident) * * @param {string} uuid – UUID or logical name of a node. * @return {promise} Node */ function getNode(uuid) { return apiService.get('/api/ironic/nodes/' + uuid) .then(function(response) { nodeErrorService.checkNodeError(response.data); return response; }) .catch(function(response) { var msg = interpolate( gettext('Unable to retrieve the Ironic node: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Retrieve a list of ports associated with a node. * * http://docs.openstack.org/developer/ironic/webapi/v1.html#get--v1-ports * * @param {string} uuid – UUID or logical name of a node. * @return {promise} List of ports */ function getPortsWithNode(uuid) { var config = { params : { node_id: uuid } }; return apiService.get('/api/ironic/ports/', config) .catch(function(response) { var msg = interpolate( gettext('Unable to retrieve the Ironic node ports: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Put the node in maintenance mode. * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * put--v1-nodes-(node_ident)-maintenance * * @param {string} uuid – UUID or logical name of a node. * @param {string} reason – Reason for why node is being put into * maintenance mode * @return {promise} Promise */ function putNodeInMaintenanceMode(uuid, reason) { var data = { maint_reason: reason ? reason : gettext("No maintenance reason given.") }; return apiService.patch('/api/ironic/nodes/' + uuid + '/maintenance', data) .catch(function(response) { var msg = interpolate( gettext('Unable to put the Ironic node in maintenance mode: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Remove the node from maintenance mode. * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * delete--v1-nodes-(node_ident)-maintenance * * @param {string} uuid – UUID or logical name of a node. * @return {promise} Promise */ function removeNodeFromMaintenanceMode(uuid) { return apiService.delete('/api/ironic/nodes/' + uuid + '/maintenance') .catch(function(response) { var msg = interpolate( gettext('Unable to remove the Ironic node ' + 'from maintenance mode: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Set the power state of the node. * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * put--v1-nodes-(node_ident)-states-power * * @param {string} uuid – UUID or logical name of a node. * @return {promise} Promise */ function powerOnNode(uuid) { var data = { state: 'on' }; return apiService.patch('/api/ironic/nodes/' + uuid + '/states/power', data) .then(function() { toastService.add('success', gettext('Refresh page to see updated power status')); }) .catch(function(response) { var msg = interpolate(gettext('Unable to power on the node: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Set the power state of the node. * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * put--v1-nodes-(node_ident)-states-power * * @param {string} uuid – UUID or logical name of a node. * @return {promise} Promise */ function powerOffNode(uuid) { var data = { state: 'off' }; return apiService.patch('/api/ironic/nodes/' + uuid + '/states/power', data) .then(function() { toastService.add('success', gettext('Refresh page to see updated power status')); }) .catch(function(response) { var msg = interpolate(gettext('Unable to power off the node: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Set the target provision state of the node. * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * put--v1-nodes-(node_ident)-states-provision * * @param {string} uuid – UUID of a node. * @param {string} verb – Provisioning verb used to move node to desired * target state * @return {promise} Promise */ function setNodeProvisionState(uuid, verb) { var data = { verb: verb }; return apiService.put('/api/ironic/nodes/' + uuid + '/states/provision', data) .then(function() { var msg = gettext( 'A request has been made to change the provisioning state of node %s'); toastService.add('success', interpolate(msg, [uuid], false)); }) .catch(function(response) { var msg = interpolate( gettext('Unable to set node provision state: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Create an Ironic node * * http://docs.openstack.org/developer/ironic/webapi/v1.html#post--v1-nodes * * @param {object} params – Object containing parameters that define * the node to be created * @return {promise} Promise */ function createNode(params) { var data = { node: params }; return apiService.post('/api/ironic/nodes/', data) .catch(function(response) { var msg = interpolate(gettext('Unable to create node: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Delete the specified node from inventory * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * delete--v1-nodes * * @param {string} nodeIdent – UUID or logical name of a node. * @return {promise} Promise */ function deleteNode(nodeIdent) { var data = { node: nodeIdent }; return apiService.delete('/api/ironic/nodes/', data) .then(function() { }) .catch(function(response) { var msg = interpolate(gettext('Unable to delete node %s: %s'), [nodeId, response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Update the definition of a specified node. * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * patch--v1-nodes-(node_ident) * * @param {string} uuid – UUID of a node. * @param {object[]} patch – Sequence of update operations * @return {promise} Promise */ function updateNode(uuid, patch) { var data = { patch: patch }; return apiService.patch('/api/ironic/nodes/' + uuid, data) .then(function() { var msg = gettext( 'Successfully updated node %s'); toastService.add('success', interpolate(msg, [uuid], false)); }) .catch(function(response) { var msg = interpolate(gettext('Unable to update node %s: %s'), [uuid, response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Validate the specified node * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * validate--v1-nodes * * @param {string} nodeId – UUID or logical name of a node. * @return {promise} Promise */ function validateNode(nodeId) { return apiService.get('/api/ironic/nodes/' + nodeId + '/validate', {node: nodeId}) .catch(function(response) { var msg = interpolate(gettext('Unable to validate node %s: %s'), [nodeId, response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Retrieve the list of Ironic drivers * * http://docs.openstack.org/developer/ironic/webapi/v1.html#get--v1-drivers * * @return {promise} Driver collection in JSON * http://docs.openstack.org/developer/ironic/webapi/v1.html#DriverList */ function getDrivers() { return apiService.get('/api/ironic/drivers/') .catch(function(response) { var msg = interpolate( gettext('Unable to retrieve Ironic drivers: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Retrieve properities of a specified driver * * http://docs.openstack.org/developer/ironic/webapi/v1.html# * get--v1-drivers-properties * * @param {string} driverName - Driver name * @returns {promise} Property list */ function getDriverProperties(driverName) { return apiService.get( '/api/ironic/drivers/' + driverName + '/properties') .catch(function(response) { var msg = interpolate( gettext('Unable to retrieve driver properties: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Create a network port * * @param {object} port – Object containing parameters that define * the port to be created * @return {promise} Promise */ function createPort(port) { var data = { port: port }; return apiService.post('/api/ironic/ports/', data) .then(function() { toastService.add('success', gettext('Port successfully created')); }) .catch(function(response) { var msg = interpolate(gettext('Unable to create port: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Delete a network port * * @param {string} portUuid – UUID of the port to be deleted * @return {promise} Promise */ function deletePort(portUuid) { var data = { port_uuid: portUuid }; return apiService.delete('/api/ironic/ports/', data) .catch(function(response) { var msg = interpolate(gettext('Unable to delete port: %s'), [response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } /** * @description Update the definition of a specified port. * * http://developer.openstack.org/api-ref/baremetal/#update-a-port * * @param {string} portUuid – UUID of a port. * @param {object[]} patch – Sequence of update operations * @return {promise} Promise */ function updatePort(portUuid, patch) { return apiService.patch('/api/ironic/ports/' + portUuid, {patch: patch}) .then(function(response) { var msg = gettext('Successfully updated port %s'); toastService.add('success', interpolate(msg, [portUuid], false)); return response.data; // The updated port }) .catch(function(response) { var msg = interpolate(gettext('Unable to update port %s: %s'), [portUuid, response.data], false); toastService.add('error', msg); return $q.reject(msg); }); } } }()); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/ironic.module.js0000775000567000056710000000500113046166232027432 0ustar jenkinsjenkins00000000000000/* * © Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP * * 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. */ (function () { 'use strict'; /** * @ngdoc overview * @ngname horizon.dashboard.admin.ironic * * @description * Provides all of the services and widgets required * to support and display Ironic related content. */ angular .module('horizon.dashboard.admin.ironic', []) .config(config); config.$inject = ['$provide', '$windowProvider']; function config($provide, $windowProvider) { $provide.constant('horizon.dashboard.admin.ironic.validHostNamePattern', '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$'); // eslint-disable-line max-len $provide.constant('horizon.dashboard.admin.ironic.validUuidPattern', '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$'); // eslint-disable-line max-len $provide.constant('horizon.dashboard.admin.ironic.validMacAddressPattern', '^[0-9A-Fa-f]{2}(:[0-9A-Fa-f]{2}){5}$'); // eslint-disable-line max-len $provide.constant('horizon.dashboard.admin.ironic.validDatapathIdPattern', '^[0-9A-Fa-f]{16}$'); // eslint-disable-line max-len var path = $windowProvider.$get().STATIC_URL + 'dashboard/admin/ironic/'; $provide.constant('horizon.dashboard.admin.ironic.basePath', path); var events = { ENROLL_NODE_SUCCESS:'horizon.dashboard.admin.ironic.ENROLL_NODE_SUCCESS', DELETE_NODE_SUCCESS:'horizon.dashboard.admin.ironic.DELETE_NODE_SUCCESS', EDIT_NODE_SUCCESS:'horizon.dashboard.admin.ironic.EDIT_NODE_SUCCESS', CREATE_PORT_SUCCESS:'horizon.dashboard.admin.ironic.CREATE_PORT_SUCCESS', DELETE_PORT_SUCCESS:'horizon.dashboard.admin.ironic.DELETE_PORT_SUCCESS', EDIT_PORT_SUCCESS:'horizon.dashboard.admin.ironic.EDIT_PORT_SUCCESS' }; $provide.constant('horizon.dashboard.admin.ironic.events', events); } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-list/0000775000567000056710000000000013046166505026227 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-list/node-list.controller.js0000775000567000056710000001355613046166232032657 0ustar jenkinsjenkins00000000000000/* * © Copyright 2016 Hewlett Packard Enterprise Development Company LP * Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .controller('IronicNodeListController', IronicNodeListController); IronicNodeListController.$inject = [ '$scope', '$rootScope', '$q', 'horizon.framework.widgets.toast.service', 'horizon.app.core.openstack-service-api.ironic', 'horizon.dashboard.admin.ironic.events', 'horizon.dashboard.admin.ironic.actions', 'horizon.dashboard.admin.ironic.maintenance.service', 'horizon.dashboard.admin.ironic.enroll-node.service', 'horizon.dashboard.admin.ironic.edit-node.service', 'horizon.dashboard.admin.ironic.node-state-transition.service' ]; function IronicNodeListController($scope, $rootScope, $q, toastService, ironic, ironicEvents, actions, maintenanceService, enrollNodeService, editNodeService, nodeStateTransitionService) { var ctrl = this; ctrl.nodes = []; ctrl.nodesSrc = []; ctrl.actions = actions; ctrl.putNodeInMaintenanceMode = putNodeInMaintenanceMode; ctrl.putNodesInMaintenanceMode = putNodesInMaintenanceMode; ctrl.removeNodeFromMaintenanceMode = removeNodeFromMaintenanceMode; ctrl.removeNodesFromMaintenanceMode = removeNodesFromMaintenanceMode; ctrl.enrollNode = enrollNode; ctrl.editNode = editNode; ctrl.refresh = refresh; ctrl.getNodeStateTransitions = getNodeStateTransitions; /** * Filtering - client-side MagicSearch * all facets for node table */ ctrl.nodeFacets = [ { label: gettext('Name'), name: 'name', singleton: true }, { label: gettext('UUID'), name: 'uuid', singleton: true }, { label: gettext('Power State'), name: 'power_state', singleton: true }, { label: gettext('Provisioning State'), name: 'provision_state', singleton: true }, { label: gettext('Maintenance'), name: 'maintenance', singleton: true }, { label: gettext('Driver'), name: 'driver', singleton: true } ]; // Listen for the creation of new nodes, and update the node list var enrollNodeHandler = $rootScope.$on(ironicEvents.ENROLL_NODE_SUCCESS, function() { init(); }); var deleteNodeHandler = $rootScope.$on(ironicEvents.DELETE_NODE_SUCCESS, function() { init(); }); var editNodeHandler = $rootScope.$on(ironicEvents.EDIT_NODE_SUCCESS, function() { init(); }); var createPortHandler = $rootScope.$on(ironicEvents.CREATE_PORT_SUCCESS, function() { init(); }); var deletePortHandler = $rootScope.$on(ironicEvents.DELETE_PORT_SUCCESS, function() { init(); }); $scope.$on('destroy', function() { enrollNodeHandler(); deleteNodeHandler(); editNodeHandler(); createPortHandler(); deletePortHandler(); }); init(); // RETRIVE NODES AND PORTS function init() { retrieveNodes(); } function retrieveNodes() { ironic.getNodes().then(onGetNodes); } function onGetNodes(response) { var promises = []; angular.forEach(response.data.items, function (node) { node.id = node.uuid; promises.push(retrievePorts(node)); }); $q.all(promises).then(function() { ctrl.nodesSrc = response.data.items; }); } function retrievePorts(node) { return ironic.getPortsWithNode(node.uuid).then( function (response) { node.ports = response.data.items; } ); } function putNodeInMaintenanceMode(node) { maintenanceService.putNodeInMaintenanceMode(node); } function putNodesInMaintenanceMode(nodes) { maintenanceService.putNodesInMaintenanceMode(nodes); } function removeNodeFromMaintenanceMode(node) { maintenanceService.removeNodeFromMaintenanceMode(node); } function removeNodesFromMaintenanceMode(nodes) { maintenanceService.removeNodesFromMaintenanceMode(nodes); } function enrollNode() { enrollNodeService.enrollNode(); } function editNode(node) { editNodeService.modal(node); } function refresh() { init(); } function getNodeStateTransitions(node) { return nodeStateTransitionService.getTransitions(node.provision_state); } } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-list/node-list.html0000664000567000056710000001764713046166232031027 0ustar jenkinsjenkins00000000000000
{$ 'Power on' | translate $} {$ 'Power off' | translate $} {$ 'Maintenance on' | translate $} {$ 'Maintenance off' | translate $} {$ 'Delete nodes' | translate $}
Node Name Instance ID Power State Provisioning State Maintenance Ports Driver Actions
{$ node.name || node.uuid $} {$ node.instance_uuid $} {$ 'No Instance' | translate $}
{$ node.power_state $}
{$ node.provision_state $} {$ node.maintenance | yesno $} {$ node.ports.length $} {$ node.driver $} {$ 'Power on' | translate $} {$ 'Power off' | translate $} {$ 'Maintenance on' | translate $} {$ 'Maintenance off' | translate $} {$ 'Delete node' | translate $} {$ 'Create port' | translate $}
  • {$ transition.label $}
  • {$ 'Edit' | translate $}
    ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-state-transition.service.js0000664000567000056710000001070613046166232032562 0ustar jenkinsjenkins00000000000000/* * © Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .service('horizon.dashboard.admin.ironic.node-state-transition.service', nodeStateTransitionService); nodeStateTransitionService.$inject = []; /** * @description Utility service for working with the node state machine * @return {void} */ function nodeStateTransitionService() { // Dictionary of NodeState objects indexed by state name var states = {}; // Create node state objects angular.forEach(['enroll', 'manageable', 'active', 'available', 'adopt failed', 'clean failed', 'inspect failed', 'clean wait', 'deploy failed', 'error'], function(state) { states[state] = new NodeState(state); }); // Add state transitions states.enroll.addTransition('manageable', 'manage'); states.manageable.addTransition('active', 'adopt'); states.manageable.addTransition('available', 'provide'); states.manageable.addTransition('manageable', 'inspect', gettext('Inspect')); states.active.addTransition('available', 'deleted'); states.available.addTransition('active', 'active'); states.available.addTransition('manageable', 'manage'); states['adopt failed'].addTransition('manageable', 'manage'); states['adopt failed'].addTransition('active', 'adopt'); states['inspect failed'].addTransition('manageable', 'manage'); states['clean wait'].addTransition('clean failed', 'abort', gettext('Abort cleaning')); states['clean failed'].addTransition('manageable', 'manage'); states['deploy failed'].addTransition('active', 'active'); states['deploy failed'].addTransition('manageable', 'deleted'); states.error.addTransition('active', 'rebuild'); states.error.addTransition('manageable', 'deleted'); /** * @description Class constructor for NodeState object. * A NodeState maintains a set of transitions to other states. * * @param {name} name – Name of state * @return {void} */ function NodeState(name) { this.name = name; this.transitions = {}; /** * @description Add a transition to a specified target state. * * @param {string} target – Name of target state * @param {string} verb – Verb used to accomplish transition * @param {string} label – Description of the transition. Optional. * @return {void} */ this.addTransition = function(target, verb, label) { this.transitions[target] = {source: this.name, target: target, verb: verb, label: angular.isDefined(label) ? label : gettext("Move to") + " " + target}; }; /** * @description Get the transition object associated with a * specified target state. * * @param {string} targetState – Name of target state * @return {object} Transition object. A value of null * is returned if a transition does not exist. */ this.getTransition = function(targetState) { return this.transitions.hasOwnProperty(targetState) ? this.transitions[targetState] : null; }; } this.getTransitions = function(sourceState) { var transitions = []; if (states.hasOwnProperty(sourceState)) { angular.forEach(states[sourceState].transitions, function(transition) { transitions.push(transition); }); } return transitions; }; } }()); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/modal-draggable.directive.js0000664000567000056710000000237213046166232031647 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .directive('modalDraggable', ModalDraggable); ModalDraggable.$inject = ['$document', '$log']; function ModalDraggable($document, $log) { return function (scope, element) { var modalContent = null; while (element) { if (element.hasClass("modal-content")) { modalContent = element; break; } element = element.parent(); } if (modalContent) { modalContent.draggable({ handle: ".modal-header" }); } else { $log.error("Unable to find parent dialog"); } }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/auto-focus.directive.js0000664000567000056710000000170213046166232030726 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .directive('autoFocus', AutoFocus); AutoFocus.$inject = ['$timeout']; function AutoFocus($timeout) { return { restrict: 'AC', link: function(scope, elem) { $timeout(function() { elem[0].focus(); }, 1000); } }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/update-patch.service.js0000664000567000056710000001375613046166232030716 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.update-patch.service', updatePatchService); updatePatchService.$inject = [ '$log' ]; function updatePatchService($log) { var service = { UpdatePatch: UpdatePatch }; /* The pdatePatch class is used to construct a set of patch instructions that transform a base object into a specified target. */ function UpdatePatch() { this.patch = []; this.status = UpdatePatch.status.OK; } UpdatePatch.status = { OK: 0, ERROR: 1, UNKNOWN_TYPE: 2 }; /** * @description Update the status of the patch with a specified code * * @param {int} status - latest status code * @return {void} */ UpdatePatch.prototype._updateStatus = function(status) { this.status = Math.max(this.status, status); }; /** * @description Check whether an item is a property * * @param {object} item - item to be tested * @return {boolean} True if the item is a number, string, or date */ function isProperty(item) { return item === null || angular.isNumber(item) || angular.isString(item) || angular.isDate(item); } /** * @description Check whether an item is a collection * * @param {object} item - item to be tested * @return {boolean} True if the item is an array or object */ function isCollection(item) { return angular.isArray(item) || angular.isObject(item); } /** * @description Add instructions to the patch for processing a * specified item * * @param {object} item - item to be added * @param {string} path - Path to the item being added * @param {string} op - add or remove * @return {void} */ UpdatePatch.prototype._processItem = function(item, path, op) { $log.info("UpdatePatch._processItem: " + path + " " + op); if (isProperty(item)) { this.patch.push({op: op, path: path, value: item}); } else if (isCollection(item)) { angular.forEach(item, function(partName, part) { this._processItem(part, path + "/" + partName, op); }); } else { this._updateStatus(UpdatePatch.status.UNKNOWN_TYPE); $log.error("Unable to process (" + op + ") item (" + path + "). " + " " + typeof item + " " + JSON.stringify(item)); } }; /** * @description Add instructions to the patch for adding a specified item * * @param {object} item - item to be added * @param {string} path - Path to the item being removed * @return {void} */ UpdatePatch.prototype._addItem = function(item, path) { this._processItem(item, path, "add"); }; /** * @description Add instructions to the patch for removing a specified item * * @param {object} item - item to be removed * @param {string} path - Path to the item being removed * @return {void} */ UpdatePatch.prototype._removeItem = function(item, path) { this._processItem(item, path, "remove"); }; /** * @description Determine the set of operations required to * transform a source version of an object into a target version, * and add them to a patch. * * @param {object} source - Source object * @param {object} target - Target object * @param {string} path - Pathname of the patched object * @return {void} */ UpdatePatch.prototype.buildPatch = function(source, target, path) { $log.info("UpdatePatch._buildPatch: " + path); var patcher = this; if (isProperty(source) && isProperty(target)) { if (source !== target) { patcher.patch.push({op: "replace", path: path, value: target}); } } else if (isCollection(source) && isCollection(target)) { angular.forEach(source, function(sourceItem, sourceItemName) { if (angular.isDefined(target[sourceItemName])) { patcher.buildPatch(sourceItem, target[sourceItemName], path + '/' + sourceItemName); } else { patcher._removeItem(sourceItem, path + '/' + sourceItemName); } }); angular.forEach(target, function(targetItem, targetItemName) { if (angular.isUndefined(source[targetItemName])) { patcher._addItem(targetItem, path + '/' + targetItemName); } }); } else if (isProperty(source) && isCollection(target) || isCollection(source) && isProperty(target)) { patcher._removeItem(source, path); patcher._addItem(target, path); } else { patcher._updateStatus(UpdatePatch.status.ERROR); $log.error("Unable to patch " + path + " " + "source = " + JSON.stringify(source) + ", " + "target = " + JSON.stringify(target)); } }; /** * @description Get the patch * * @return {object} An object with two properties: * patch: Array of patch instructions compatible with the Ironic * node/port update commands * status: Code indicating whether patch creation was successful * */ UpdatePatch.prototype.getPatch = function() { return {patch: angular.copy(this.patch), status: this.status}; }; return service; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/0000775000567000056710000000000013046166505026701 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/sections/0000775000567000056710000000000013046166505030530 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/sections/overview.html0000664000567000056710000000374513046166232033272 0ustar jenkinsjenkins00000000000000

    General


    Name
    {$ ctrl.node.name | noValue $}
    Maintenance
    {$ ctrl.node.maintenance | yesno $}
    Maintenance Reason
    {$ ctrl.node.maintenance_reason | noValue $}
    Inspection Started At
    {$ ctrl.node.inspection_started_at | date: 'medium' | noValue $}
    Inspection Finished At
    {$ ctrl.node.inspection_finished_at | date: 'medium' | noValue $}
    Reservation
    {$ ctrl.node.reservation | noValue $}
    Console Enabled
    {$ ctrl.node.console_enabled | yesno $}

    Provisioning Status


    Instance ID
    {$ ctrl.node.instance_uuid | noValue $}
    Power State
    {$ ctrl.node.power_state | noValue $}
    Target Power State
    {$ ctrl.node.target_power_state | noValue $}
    Provision State
    {$ ctrl.node.provision_state | noValue $}
    Target Provision State
    {$ ctrl.node.target_provision_state | noValue $}
    Clean Step
    {$ ctrl.node.clean_step $}
    Last Error
    {$ ctrl.node.last_error | noValue $}
    Updated At
    {$ ctrl.node.updated_at | date: 'medium' | noValue $}
    ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/sections/configuration.html0000664000567000056710000002405213046166232034265 0ustar jenkinsjenkins00000000000000

    General


    Node ID
    {$ ctrl.node.uuid | noValue $}
    Chassis ID
    {$ ctrl.node.chassis_uuid | noValue $}
    Created At
    {$ ctrl.node.created_at | date:'medium' | noValue $}

    Ports


    {$ 'Create port' | translate $} {$ 'Delete ports' | translate $}
    MAC Address Properties Actions
    {$ port.address $}
    • pxe_enabled: {$ port.pxe_enabled $}
    • {$ propertyObject $}:
    {$ ::'Edit port' | translate $} {$ ::'Delete port' | translate $}

    Driver Info


    Driver
    {$ ctrl.node.driver | noValue $}
    SSH Address
    {$ ctrl.node.driver_info.ssh_address | noValue $}
    SSH Port
    {$ ctrl.node.driver_info.ssh_port | noValue $}
    SSH Username
    {$ ctrl.node.driver_info.ssh_username | noValue $}
    SSH Key File
    {$ ssh_key_filename | noValue $}
    SSH Password
    {$ ssh_password | noValue $}
    SSH Key Contents
    {$ ssh_key_contents | noValue $}
    SSH terminal port
    {$ ctrl.node.driver_info.ssh_terminal_port | noValue $}
    Virtualization Software
    {$ ctrl.node.driver_info.ssh_virt_type | noValue $}
    Deploy Kernel
    {$ ctrl.node.driver_info.deploy_kernel | noValue $} {$ ctrl.node.driver_info.deploy_kernel | noValue $}
    Deploy Ramdisk
    {$ ctrl.node.driver_info.deploy_ramdisk | noValue $} {$ ctrl.node.driver_info.deploy_ramdisk | noValue $}
    {$ id $}
    {$ value $}

    Driver Validation


    Interface Valid Reason
    {$ item.id $} {$ item.reason $}

    Properties


    {$ propertyName $}
    {$ propertyValue | noValue $}

    Instance Info


    Instance Name
    {$ ctrl.node.instance_info.display_name | noValue $}
    Ramdisk
    {$ ctrl.node.instance_info.ramdisk | noValue $}
    Kernel
    {$ ctrl.node.instance_info.kernel | noValue $}
    Image Source
    {$ ctrl.node.instance_info.image_source | noValue $}
    Root GB
    {$ ctrl.node.instance_info.root_gb | noValue $}
    {$ id $}
    {$ value | noValue $}

    Extra


    {$ propertyName $}
    {$ propertyValue | noValue $}
    ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.js0000775000567000056710000002006713046166232033776 0ustar jenkinsjenkins00000000000000/* * Copyright 2015 Hewlett Packard Enterprise Development Company LP * Copyright 2016 Cray 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. */ (function () { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .controller('horizon.dashboard.admin.ironic.NodeDetailsController', IronicNodeDetailsController); IronicNodeDetailsController.$inject = [ '$scope', '$rootScope', '$location', 'horizon.framework.widgets.toast.service', 'horizon.app.core.openstack-service-api.ironic', 'horizon.dashboard.admin.ironic.events', 'horizon.dashboard.admin.ironic.actions', 'horizon.dashboard.admin.ironic.basePath', 'horizon.dashboard.admin.ironic.edit-node.service', 'horizon.dashboard.admin.ironic.edit-port.service', 'horizon.dashboard.admin.ironic.maintenance.service', 'horizon.dashboard.admin.ironic.node-state-transition.service', 'horizon.dashboard.admin.ironic.validUuidPattern' ]; function IronicNodeDetailsController($scope, $rootScope, $location, toastService, ironic, ironicEvents, actions, basePath, editNodeService, editPortService, maintenanceService, nodeStateTransitionService, validUuidPattern) { var ctrl = this; var path = basePath + '/node-details/sections/'; ctrl.noPortsText = gettext('No network ports have been defined'); ctrl.actions = actions; ctrl.sections = [ { heading: gettext('Overview'), templateUrl: path + 'overview.html' }, { heading: gettext('Configuration'), templateUrl: path + 'configuration.html' } ]; ctrl.node = null; ctrl.nodeValidation = []; ctrl.nodeStateTransitions = []; ctrl.ports = []; ctrl.portsSrc = []; ctrl.basePath = basePath; ctrl.re_uuid = new RegExp(validUuidPattern); ctrl.isUuid = isUuid; ctrl.getVifPortId = getVifPortId; ctrl.putNodeInMaintenanceMode = putNodeInMaintenanceMode; ctrl.removeNodeFromMaintenanceMode = removeNodeFromMaintenanceMode; ctrl.editNode = editNode; ctrl.createPort = createPort; ctrl.deletePort = deletePort; ctrl.editPort = editPort; ctrl.refresh = refresh; $scope.emptyObject = function(obj) { return angular.isUndefined(obj) || Object.keys(obj).length === 0; }; var editNodeHandler = $rootScope.$on(ironicEvents.EDIT_NODE_SUCCESS, function() { init(); }); var createPortHandler = $rootScope.$on(ironicEvents.CREATE_PORT_SUCCESS, function() { init(); }); var deletePortHandler = $rootScope.$on(ironicEvents.DELETE_PORT_SUCCESS, function() { init(); $scope.$broadcast('hzTable:clearSelected'); }); $scope.$on('$destroy', function() { editNodeHandler(); createPortHandler(); deletePortHandler(); }); init(); /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.init * @description Initialize the controller instance based on the * current page url. * * @return {void} */ function init() { // Fetch the Node ID from the URL. var pattern = /(.*\/admin\/ironic\/)(.+)\/(detail)?/; var uuid = $location.absUrl().match(pattern)[2]; retrieveNode(uuid).then(function () { ctrl.nodeStateTransitions = nodeStateTransitionService.getTransitions(ctrl.node.provision_state); retrievePorts(uuid); ironic.validateNode(uuid).then(function(response) { var nodeValidation = []; angular.forEach(response.data, function(status) { status.id = status.interface; nodeValidation.push(status); }); ctrl.nodeValidation = nodeValidation; }); }); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.retrieveNode * @description Retrieve the node instance for a specified node id, * and store it in the controller instance. * * @param {string} uuid – Node name or UUID * @return {promise} promise */ function retrieveNode(uuid) { return ironic.getNode(uuid).then(function (response) { ctrl.node = response.data; ctrl.node.id = uuid; }); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.retrievePorts * @description Retrieve the ports associated with a specified node, * and store them in the controller instance. * * @param {string} nodeId – Node name or UUID * @return {void} */ function retrievePorts(nodeId) { ironic.getPortsWithNode(nodeId).then(function (response) { ctrl.portsSrc = response.data.items; ctrl.portsSrc.forEach(function(port) { port.id = port.uuid; port.name = port.address; }); }); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.isUuid * @description Test whether a string is an OpenStack UUID * * @param {string} str – string * @return {boolean} True if the string is an OpenStack UUID, * otherwise false */ function isUuid(str) { return !!str.match(ctrl.re_uuid); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.getVifPortId * @description Get the vif_port_id property of a specified port * * @param {object} port – instance of port * @return {string} Value of vif_port_id property or * "" if the property does not exist */ function getVifPortId(port) { return angular.isDefined(port.extra) && angular.isDefined(port.extra.vif_port_id) ? port.extra.vif_port_id : ""; } function putNodeInMaintenanceMode() { maintenanceService.putNodeInMaintenanceMode(ctrl.node); } function removeNodeFromMaintenanceMode() { maintenanceService.removeNodeFromMaintenanceMode(ctrl.node); } function editNode() { editNodeService.modal(ctrl.node); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.createPort * @description Initiate creation of a newtwork port for the current * node * * @return {void} */ function createPort() { ctrl.actions.createPort(ctrl.node); } /** * @description: Edit a specified port * * @param {port} port - Port to be edited * @return {void} */ function editPort(port) { editPortService.modal(port, ctrl.node).then(function() { ctrl.refresh(); }); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.deletePort * @description Delete a list of ports * * @param {port []} ports – ports to be deleted * @return {void} */ function deletePort(ports) { actions.deletePort(ports); } /** * @name horizon.dashboard.admin.ironic.NodeDetailsController.refresh * @description Update node information * * @return {void} */ function refresh() { init(); } } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.html0000664000567000056710000000417113046166232032137 0ustar jenkinsjenkins00000000000000
    {$ 'Power on' | translate $} {$ 'Power off' | translate $} {$ 'Maintenance on' | translate $} {$ 'Maintenance off' | translate $}
  • {$ transition.label $}
  • {$ 'Edit' | translate $}
    ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-details/node-details.controller.spec.js0000775000567000056710000001230313046166232034721 0ustar jenkinsjenkins00000000000000/* * Copyright 2015 Hewlett Packard Enterprise Development Company LP * Copyright 2016 Cray 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. */ (function () { 'use strict'; describe('horizon.dashboard.admin.ironic.node-details', function () { var ctrl, $q, nodeStateTransitionService; var nodeUuid = "0123abcd-0123-4567-abcd-0123456789ab"; var nodeName = "herp"; var numPorts = 2; function portUuid(nodeUuid, index) { return '' + index + index + nodeUuid.substring(2); } function portMacAddr(index) { var mac = '' + index + index; for (var i = 0; i < 5; i++) { mac += ':' + index + index; } return mac; } function createPort(nodeUuid, index, extra) { var port = {uuid: portUuid(nodeUuid, index), address: portMacAddr(index)}; if (angular.isDefined(extra)) { port.extra = extra; } return port; } function createNode(name, uuid) { return {name: name, uuid: uuid, provision_state: 'enroll'}; } var ironicAPI = { getNode: function (uuid) { var node = createNode(nodeName, uuid); return $q.when({data: node}); }, getPortsWithNode: function (uuid) { var ports = []; for (var i = 0; i < numPorts; i++) { ports.push(createPort(uuid, i)); } return $q.when({data: {items: ports}}); }, validateNode: function() { return $q.when({}); } }; beforeEach(module('horizon.dashboard.admin.ironic')); beforeEach(module(function($provide) { $provide.value('horizon.app.core.openstack-service-api.ironic', ironicAPI); })); beforeEach(module(function($provide) { $provide.value('horizon.framework.widgets.toast.service', {}); })); beforeEach(module(function($provide) { $provide.value('horizon.dashboard.admin.ironic.edit-node.service', {}); })); beforeEach(module(function($provide) { $provide.value('horizon.dashboard.admin.ironic.maintenance.service', {}); })); beforeEach(inject(function ($injector, _$rootScope_, _$location_) { var scope = _$rootScope_.$new(); $q = $injector.get('$q'); var controller = $injector.get('$controller'); var $location = _$location_; $location.path('/admin/ironic/' + nodeUuid + '/'); nodeStateTransitionService = $injector.get( 'horizon.dashboard.admin.ironic.node-state-transition.service'); ctrl = controller( 'horizon.dashboard.admin.ironic.NodeDetailsController', {$scope: scope, $location: $location, 'horizon.dashboard.admin.ironic.edit-port.service': {}, 'horizon.dashboard.admin.ironic.actions': {}}); scope.$apply(); })); it('controller should be defined', function () { expect(ctrl).toBeDefined(); }); it('should have a basePath', function () { expect(ctrl.basePath).toBeDefined(); }); it('should have a node', function () { expect(ctrl.node).toBeDefined(); var node = createNode(nodeName, nodeUuid); node.id = node.uuid; expect(ctrl.node).toEqual(node); }); it('should have ports', function () { expect(ctrl.portsSrc).toBeDefined(); expect(ctrl.portsSrc.length).toEqual(numPorts); var ports = []; for (var i = 0; i < numPorts; i++) { var port = createPort(ctrl.node.uuid, i); port.id = port.uuid; port.name = port.address; ports.push(port); } expect(ctrl.portsSrc).toEqual(ports); }); it('should have a uuid regular expression pattern', function () { expect(ctrl.re_uuid).toBeDefined(); }); it('should have an isUuid function', function () { expect(ctrl.isUuid).toBeDefined(); expect(ctrl.isUuid(ctrl.node.uuid)).toEqual(true); expect(ctrl.isUuid("not a uuid")).toEqual(false); }); it('should have a getVifPortId function', function () { expect(ctrl.getVifPortId).toBeDefined(); expect(ctrl.getVifPortId(createPort(ctrl.node.uuid, 1))).toEqual(""); var extra = {vif_port_id: "port_uuid"}; expect(ctrl.getVifPortId(createPort(ctrl.node.uuid, 1, extra))). toEqual("port_uuid"); }); it('should have node-state-transitions', function () { expect(ctrl.nodeStateTransitions).toBeDefined(); expect(ctrl.nodeStateTransitions).toEqual( nodeStateTransitionService.getTransitions(ctrl.node.provision_state)); }); it('should have node-validation', function () { expect(ctrl.nodeValidation).toBeDefined(); expect(ctrl.nodeValidation).toEqual([]); }); }); })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/node-actions.service.js0000775000567000056710000001742013046166232030715 0ustar jenkinsjenkins00000000000000/* * © Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP * Copyright 2016 Cray 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. */ (function () { 'use strict'; var POWER_STATE_ON = 'power on'; var POWER_STATE_OFF = 'power off'; angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.actions', actions); actions.$inject = [ 'horizon.app.core.openstack-service-api.ironic', 'horizon.framework.widgets.toast.service', 'horizon.dashboard.admin.ironic.events', 'horizon.framework.widgets.modal.deleteModalService', 'horizon.dashboard.admin.ironic.create-port.service', '$q', '$rootScope' ]; function actions(ironic, toastService, ironicEvents, deleteModalService, createPortService, $q, $rootScope) { var service = { createPort: createPort, deleteNode: deleteNode, deletePort: deletePort, powerOn: powerOn, powerOff: powerOff, powerOnAll: powerOnNodes, powerOffAll: powerOffNodes, putNodeInMaintenanceMode: putInMaintenanceMode, removeNodeFromMaintenanceMode: removeFromMaintenanceMode, putAllInMaintenanceMode: putNodesInMaintenanceMode, removeAllFromMaintenanceMode: removeNodesFromMaintenanceMode, setProvisionState: setProvisionState }; return service; function deleteNode(nodes) { var context = { labels: { title: ngettext("Delete Node", "Delete Nodes", nodes.length), message: ngettext('Are you sure you want to delete node "%s"? ' + 'This action cannot be undone.', 'Are you sure you want to delete nodes "%s"? ' + 'This action cannot be undone.', nodes.length), submit: ngettext("Delete Node", "Delete Nodes", nodes.length), success: ngettext('Successfully deleted node "%s"', 'Successfully deleted nodes "%s"', nodes.length), error: ngettext('Unable to delete node "%s"', 'Unable to delete nodes "%s"', nodes.length) }, deleteEntity: ironic.deleteNode, successEvent: ironicEvents.DELETE_NODE_SUCCESS }; return deleteModalService.open($rootScope, nodes, context); } // power state function powerOn(node) { if (node.power_state !== POWER_STATE_OFF) { var msg = gettext("Node %s is not powered off."); return $q.reject(interpolate(msg, [node], false)); } return ironic.powerOnNode(node.uuid).then( function() { // Set power state to be indeterminate node.power_state = null; } ); } function powerOff(node) { if (node.power_state !== POWER_STATE_ON) { var msg = gettext("Node %s is not powered on."); return $q.reject(interpolate(msg, [node], false)); } return ironic.powerOffNode(node.uuid).then( function() { // Set power state to be indeterminate node.power_state = null; } ); } function powerOnNodes(nodes) { return applyFuncToNodes(powerOn, nodes); } function powerOffNodes(nodes) { return applyFuncToNodes(powerOff, nodes); } // maintenance function putInMaintenanceMode(node, maintReason) { if (node.maintenance !== false) { var msg = gettext("Node %s is already in maintenance mode."); return $q.reject(interpolate(msg, [node], false)); } return ironic.putNodeInMaintenanceMode(node.uuid, maintReason).then( function () { node.maintenance = true; node.maintenance_reason = maintReason; } ); } function removeFromMaintenanceMode(node) { if (node.maintenance !== true) { var msg = gettext("Node %s is not in maintenance mode."); return $q.reject(interpolate(msg, [node], false)); } return ironic.removeNodeFromMaintenanceMode(node.uuid).then( function () { node.maintenance = false; node.maintenance_reason = ""; } ); } function putNodesInMaintenanceMode(nodes, maintReason) { return applyFuncToNodes(putInMaintenanceMode, nodes, maintReason); } function removeNodesFromMaintenanceMode(nodes) { return applyFuncToNodes(removeFromMaintenanceMode, nodes); } /* * @name horizon.dashboard.admin.ironic.actions.setProvisionState * @description Set the provisioning state of a specified node * * @param {object} args - Object with two properties named 'node' * and 'verb'. * node: node object. * verb: string the value of which is the verb used to move * the node to the desired target state for the node. */ function setProvisionState(args) { ironic.setNodeProvisionState(args.node.uuid, args.verb); } function createPort(node) { return createPortService.modal(node); } function deletePort(ports) { var context = { labels: { title: ngettext("Delete Port", "Delete Ports", ports.length), message: ngettext('Are you sure you want to delete port "%s"? ' + 'This action cannot be undone.', 'Are you sure you want to delete ports "%s"? ' + 'This action cannot be undone.', ports.length), submit: ngettext("Delete Port", "Delete Ports", ports.length), success: ngettext('Successfully deleted port "%s"', 'Successfully deleted ports "%s"', ports.length), error: ngettext('Unable to delete port "%s"', 'Unable to delete portss "%s"', ports.length) }, deleteEntity: ironic.deletePort, successEvent: ironicEvents.DELETE_PORT_SUCCESS }; return deleteModalService.open($rootScope, ports, context); } /* * @name horizon.dashboard.admin.ironic.actions.applyFuncToNodes * @description Apply a specified function to each member of a * collection of nodes * * @param {function} fn – Function to be applied. * The function should accept a node as the first argument. An optional * second argument can be used to provide additional information. * @param {Array} nodes - Collection of nodes * @param {object} extra - Additional argument passed to the function * @return {promise} - Single promise that represents the combined * return status from all function invocations. The promise is rejected * if any individual call fails. */ function applyFuncToNodes(fn, nodes, extra) { var promises = []; angular.forEach(nodes, function(node) { promises.push(fn(node, extra)); }); return $q.all(promises); } } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/edit-port/0000775000567000056710000000000013046166505026240 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/edit-port/edit-port.controller.js0000664000567000056710000001041513046166232032665 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; var UNABLE_TO_UPDATE_CONNECTIVITY_ATTR_MSG = gettext("This field is disabled because a port cannot have any connectivity attributes (pxe_enabled, local_link_connection, portgroup_id) updated unless its associated node is in an enroll, inspecting, mangeable state; or in maintenance mode."); // eslint-disable-line max-len /** * Controller used to edit a specified node port */ angular .module('horizon.dashboard.admin.ironic') .controller('EditPortController', EditPortController); EditPortController.$inject = [ '$rootScope', '$controller', '$uibModalInstance', '$log', '$q', 'horizon.app.core.openstack-service-api.ironic', 'horizon.dashboard.admin.ironic.events', 'horizon.dashboard.admin.ironic.update-patch.service', 'port', 'node' ]; function EditPortController($rootScope, $controller, $uibModalInstance, $log, $q, ironic, ironicEvents, updatePatchService, port, node) { var ctrl = this; $controller('BasePortController', {ctrl: ctrl, $uibModalInstance: $uibModalInstance}); ctrl.modalTitle = gettext("Edit Port"); ctrl.submitButtonTitle = gettext("Update Port"); var cannotEditConnectivityAttr = !(node.maintenance || (node.provision_state === "enroll" || node.provision_state === "inspecting" || node.provision_state === "manageable")); // Initialize form fields ctrl.port.address = port.address; ctrl.pxeEnabled.value = port.pxe_enabled ? 'True' : 'False'; if (cannotEditConnectivityAttr) { ctrl.pxeEnabled.disabled = true; ctrl.pxeEnabled.info = UNABLE_TO_UPDATE_CONNECTIVITY_ATTR_MSG; } angular.forEach( ['port_id', 'switch_id', 'switch_info'], function(prop) { if (angular.isDefined(port.local_link_connection[prop])) { ctrl.localLinkConnection[prop].value = port.local_link_connection[prop]; } }); if (cannotEditConnectivityAttr) { ctrl.localLinkConnection.$setDisabled( true, UNABLE_TO_UPDATE_CONNECTIVITY_ATTR_MSG); } ctrl.port.extra = angular.copy(port.extra); /** * Apply updates to the port being edited * * @return {void} */ ctrl.updatePort = function() { var patcher = new updatePatchService.UpdatePatch(); $log.info("Updating port " + JSON.stringify(port)); patcher.buildPatch(port.address, ctrl.port.address, "/address"); patcher.buildPatch(port.pxe_enabled ? 'True' : 'False', ctrl.pxeEnabled.value, "/pxe_enabled"); patcher.buildPatch(port.local_link_connection, ctrl.localLinkConnection.$toPortAttr(), "/local_link_connection"); patcher.buildPatch(port.extra, ctrl.port.extra, "/extra"); var patch = patcher.getPatch(); $log.info("patch = " + JSON.stringify(patch.patch)); if (patch.status === updatePatchService.UpdatePatch.status.OK) { ironic.updatePort(port.uuid, patch.patch).then(function(port) { $rootScope.$emit(ironicEvents.EDIT_PORT_SUCCESS); $uibModalInstance.close(port); }); } else { toastService.add('error', gettext('Unable to create port update patch.')); } }; ctrl.submit = function() { ctrl.updatePort(); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/edit-port/edit-port.service.js0000664000567000056710000000261313046166232032143 0ustar jenkinsjenkins00000000000000/* * Copyright 2017 Cray 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. */ (function() { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.edit-port.service', editPortService); editPortService.$inject = [ '$uibModal', 'horizon.dashboard.admin.ironic.basePath' ]; function editPortService($uibModal, basePath) { var service = { modal: modal }; function modal(port, node) { var options = { controller: 'EditPortController as ctrl', backdrop: 'static', resolve: { port: function() { return port; }, node: function() { return node; } }, templateUrl: basePath + '/base-port/base-port.html' }; return $uibModal.open(options).result; } return service; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-node/0000775000567000056710000000000013046166505026166 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-node/base-node.controller.js0000664000567000056710000002265013046166232032545 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; /** * Controller used to support operations on an Ironic node */ angular .module('horizon.dashboard.admin.ironic') .controller('BaseNodeController', BaseNodeController); BaseNodeController.$inject = [ '$uibModalInstance', 'horizon.app.core.openstack-service-api.ironic', 'horizon.app.core.openstack-service-api.glance', 'horizon.dashboard.admin.ironic.base-node.service', 'horizon.dashboard.admin.ironic.validHostNamePattern', '$log', 'ctrl' ]; function BaseNodeController($uibModalInstance, ironic, glance, baseNodeService, validHostNamePattern, $log, ctrl) { ctrl.validHostNameRegex = new RegExp(validHostNamePattern); ctrl.drivers = null; ctrl.images = null; ctrl.loadingDriverProperties = false; // Object containing the set of properties associated with the currently // selected driver ctrl.driverProperties = null; ctrl.driverPropertyGroups = null; ctrl.modalTitle = gettext("Node"); ctrl.submitButtonTitle = gettext("Submit"); /* A property-collection is a set of properties that will be displayed in the node view as a minimal browser ui that supports: - adding new properties - displaying the list of properties in the set - changing the value of properties */ ctrl.propertyCollections = [ {id: "properties", title: "Properties", addPrompt: "Add Property", placeholder: "Property Name" }, {id: "extra", title: "Extras", addPrompt: "Add Extra", placeholder: "Extra Property Name" }]; // Node object suitable for Ironic api ctrl.node = { name: null, driver: null, driver_info: {}, properties: {}, extra: {} }; /** * @description Get the list of currently active Ironic drivers * * @return {void} */ ctrl._loadDrivers = function() { return ironic.getDrivers().then(function(response) { ctrl.drivers = response.data.items; }); }; /** * @description Get the list of images from Glance * * @return {void} */ ctrl._getImages = function() { glance.getImages().then(function(response) { ctrl.images = response.data.items; }); }; /** * @description Check whether a group contains required properties * * @param {DriverProperty[]} group - Property group * @return {boolean} Return true if the group contains required * properties, false otherwise */ function driverPropertyGroupHasRequired(group) { var hasRequired = false; for (var i = 0; i < group.length; i++) { if (group[i].required) { hasRequired = true; break; } } return hasRequired; } /** * @description Convert array of driver property groups to a string * * @param {array[]} groups - Array for driver property groups * @return {string} Output string */ function driverPropertyGroupsToString(groups) { var output = []; angular.forEach(groups, function(group) { var groupStr = []; angular.forEach(group, function(property) { groupStr.push(property.name); }); groupStr = groupStr.join(", "); output.push(['[', groupStr, ']'].join("")); }); output = output.join(", "); return ['[', output, ']'].join(""); } /** * @description Comaprison function used to sort driver property groups * * @param {DriverProperty[]} group1 - First group * @param {DriverProperty[]} group2 - Second group * @return {integer} Return: * < 0 if group1 should precede group2 in an ascending ordering * > 0 if group2 should precede group1 * 0 if group1 and group2 are considered equal from ordering perpsective */ function compareDriverPropertyGroups(group1, group2) { var group1HasRequired = driverPropertyGroupHasRequired(group1); var group2HasRequired = driverPropertyGroupHasRequired(group2); if (group1HasRequired === group2HasRequired) { if (group1.length === group2.length) { return group1[0].name.localeCompare(group2[0].name); } else { return group1.length - group2.length; } } else { return group1HasRequired ? -1 : 1; } return 0; } /** * @description Order driver properties in the form using the following * rules: * * (1) Properties that are related to one another should occupy adjacent * locations in the form * * (2) Required properties with no dependents should be located at the * top of the form * * @return {void} */ ctrl._sortDriverProperties = function() { // Build dependency graph between driver properties var graph = new baseNodeService.Graph(); // Create vertices angular.forEach(ctrl.driverProperties, function(property, name) { graph.addVertex(name, property); }); /* eslint-disable no-unused-vars */ // Create edges angular.forEach(ctrl.driverProperties, function(property, name) { var activators = property.getActivators(); if (activators) { angular.forEach(activators, function(unused, activatorName) { graph.addEdge(name, activatorName); }); } }); /* eslint-enable no-unused-vars */ // Perform depth-first-search to find groups of related properties var groups = []; graph.dfs( function(vertexList, components) { // Sort properties so that those with the largest number of // immediate dependents are the top of the list vertexList.sort(function(vertex1, vertex2) { return vertex2.adjacents.length - vertex1.adjacents.length; }); // Build component and add to list var component = new Array(vertexList.length); angular.forEach(vertexList, function(vertex, index) { component[index] = vertex.data; }); components.push(component); }, groups); groups.sort(compareDriverPropertyGroups); $log.debug("Found the following property groups: " + driverPropertyGroupsToString(groups)); return groups; }; /** * @description Get the properties associated with a specified driver * * @param {string} driverName - Name of driver * @return {void} */ ctrl.loadDriverProperties = function(driverName) { ctrl.node.driver = driverName; ctrl.node.driver_info = {}; ctrl.loadingDriverProperties = true; ctrl.driverProperties = null; ctrl.driverPropertyGroups = null; return ironic.getDriverProperties(driverName).then(function(response) { ctrl.driverProperties = {}; angular.forEach(response.data, function(desc, property) { ctrl.driverProperties[property] = new baseNodeService.DriverProperty(property, desc, ctrl.driverProperties); }); ctrl.driverPropertyGroups = ctrl._sortDriverProperties(); ctrl.loadingDriverProperties = false; }); }; /** * @description Cancel the current node operation * * @return {void} */ ctrl.cancel = function() { $uibModalInstance.dismiss('cancel'); }; /** * @description Check whether the specified property already exists * * @param {string} collectionId - Collection ID * @param {string} propertyName - Name of the property * @return {boolean} True if the property already exists, * otherwise false */ ctrl.collectionCheckPropertyUnique = function(collectionId, propertyName) { return !(propertyName in ctrl.node[collectionId]); }; /** * @description Delete a node metadata property * * @param {string} collectionId - Collection ID * @param {string} propertyName - Name of the property * @return {void} */ ctrl.collectionDeleteProperty = function(collectionId, propertyName) { delete ctrl.node[collectionId][propertyName]; }; /** * @description Check whether a specified driver property is * currently active * * @param {string} property - Driver property * @return {boolean} True if the property is active, false otherwise */ ctrl.isDriverPropertyActive = function(property) { return property.isActive(); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-node/base-node.service.js0000664000567000056710000005515113046166232032024 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; var REQUIRED = " " + gettext("Required") + "."; var SELECT_OPTIONS_REGEX = new RegExp( gettext('(?:[Oo]ne of )(?!this)((?:(?:"[^"]+"|[^,\\. ]+)(?:, |\\.))+)')); var DEFAULT_IS_REGEX = new RegExp(gettext('default (?:value )?is ([^"\\. ]+|"[^"]+")')); var DEFAULTS_TO_REGEX = new RegExp(gettext('Defaults to ([^"\\. ]+|"[^"]+")')); var DEFAULT_IN_PARENS_REGEX = new RegExp(gettext(' ([^" ]+|"[^"]+") \\(Default\\)')); var DEFAULT_REGEX_LIST = [DEFAULT_IS_REGEX, DEFAULTS_TO_REGEX, DEFAULT_IN_PARENS_REGEX]; var ONE_OF_REGEX = new RegExp(gettext('One of this, (.*) must be specified\\.')); var NOT_INSIDE_MATCH = -1; var VALID_PORT_REGEX = new RegExp('^\\d+$'); var VALID_IPV4_ADDRESS = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; // eslint-disable-line max-len var VALID_IPV6_ADDRESS = "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"; // eslint-disable-line max-len angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.base-node.service', baseNodeService); baseNodeService.$inject = [ '$uibModal', '$log', 'horizon.dashboard.admin.ironic.validHostNamePattern', 'horizon.dashboard.admin.ironic.validUuidPattern' ]; function baseNodeService($uibModal, $log, validHostNamePattern, validUuidPattern) { var service = { DriverProperty: DriverProperty, PostfixExpr: PostfixExpr, Graph: Graph }; var VALID_ADDRESS_HOSTNAME_REGEX = new RegExp(VALID_IPV4_ADDRESS + "|" + VALID_IPV6_ADDRESS + "|" + validHostNamePattern); var VALID_IMAGE_REGEX = new RegExp(validUuidPattern + "|" + "^(https?|file)://.+$"); /** The DriverProperty class is used to represent an ironic driver property. It is currently used by the base-node form to support property display, value assignment and validation. The following rules are used to extract information about a property from the description returned by the driver. 1. If the description ends with " Required." a value must be supplied for the property. 2. The following syntax is used to extract default values from property descriptions. Default is (|.) default is “” default value is (|.) default value is “” Defaults to (|.) Defaults to “ (Default) 3. The following syntax is used to determine whether a property is considered active. In the example below if the user specifies a value for , properties 2 to n will be tagged inactive, and hidden from view. All properties are considered to be required. One of this, , , …, or must be specified. 4. The following syntax is used to determine whether a property is restricted to a set of enumerated values. The property will be displayed as an HTML select element. [Oo]ne of , "", …, . 5. The following syntax is used to determine whether a property is active and required based on the value of another property. If the property is not active it will not be displayed. Required|Used only if is set to (or "")*. Notes: 1. The properties "deploy_kernel" and "deploy_ramdisk" are assumed to accept Glance image uuids as valid values. 2. Property names ending in _port are assumed to only accept postive integer values 3. Property names ending in _address are assumed to only accept valid IPv4 and IPv6 addresses; and hostnames */ /** * @description Construct a new driver property * * @class DriverProperty * @param {string} name - Name of property * @param {string} desc - Description of property * @param {object} propertySet - Set of properties to which this one belongs * * @property {string} defaultValue - Default value of the property * @property {string[]} selectOptions - If the property is limited to a * set of enumerated values then selectOptions will be an array of those * values, otherwise null * @property {boolean} required - Boolean value indicating whether a value * must be supplied for this property if it is active * @property {PostfixExpr} isActiveExpr - Null if this property is always * active; otherwise, a boolean expression that when evaluated will * return whether this variable is active. A property is considered * active if its role is not eliminated by the values of other * properties in the property-set. * @property {string} inputValue - User assigned value for this property * @property {regexp} validValueRegex - Regular expression used to * determine whether an input value is valid. * @returns {object} Driver property */ function DriverProperty(name, desc, propertySet) { this.name = name; this.desc = desc; this.propertySet = propertySet; // Determine whether this property should be presented as a selection this.selectOptions = this._analyzeSelectOptions(); this.required = null; // Initialize to unknown // Expression to be evaluated to determine whether property is active. // By default the property is considered active. this.isActiveExpr = null; var result = this._analyzeRequiredOnlyDependencies(); if (result) { this.required = result[0]; this.isActiveExpr = result[1]; } if (!this.isActiveExpr) { result = this._analyzeOneOfDependencies(); if (result) { this.required = result[0]; this.isActiveExpr = result[1]; } } if (this.required === null) { this.required = desc.endsWith(REQUIRED); } this.defaultValue = this._getDefaultValue(); this.inputValue = this.defaultValue; // Infer that property is a boolean that can be represented as a // True/False selection if (this.selectOptions === null && (this.defaultValue === "True" || this.defaultValue === "False")) { this.selectOptions = ["True", "False"]; } this.validValueRegex = _determineValidValueRegex(this.name); } /** * @description Return a regular expression that can be used to * validate the value of a specified property * * @param {string} propertyName - Name of property * @return {regexp} Regular expression object or undefined */ function _determineValidValueRegex(propertyName) { var regex; if (propertyName.endsWith("_port")) { regex = VALID_PORT_REGEX; } else if (propertyName.endsWith("_address")) { regex = VALID_ADDRESS_HOSTNAME_REGEX; } else if (propertyName === "deploy_kernel") { regex = VALID_IMAGE_REGEX; } else if (propertyName === "deploy_ramdisk") { regex = VALID_IMAGE_REGEX; } return regex; } DriverProperty.prototype.isActive = function() { if (!this.isActiveExpr) { return true; } var ret = this.isActiveExpr.evaluate(this.propertySet); return ret[0] === PostfixExpr.status.OK && typeof ret[1] === "boolean" ? ret[1] : true; }; /** * @description Get a regular expression object that can be used to * determine whether a value is valid for this property * * @return {regexp} Regular expression object or undefined */ DriverProperty.prototype.getValidValueRegex = function() { return this.validValueRegex; }; /** * @description Must a value be provided for this property * * @return {boolean} True if a value must be provided for this property */ DriverProperty.prototype.isRequired = function() { return this.required; }; DriverProperty.prototype._analyzeSelectOptions = function() { var match = this.desc.match(SELECT_OPTIONS_REGEX); if (!match) { return null; } var matches = match[1].substring(0, match[1].length - 1).split(", "); var options = []; angular.forEach(matches, function(match) { options.push(trimQuotes(match)); }); return options; }; /** * @description Get the list of select options for this property * * @return {string[]} null if this property is not selectable; else, * an array of selectable options */ DriverProperty.prototype.getSelectOptions = function() { return this.selectOptions; }; /** * @description Remove leading/trailing double-quotes from a string * * @param {string} str - String to be trimmed * @return {string} trim'd string */ function trimQuotes(str) { return str.charAt(0) === '"' ? str.substring(1, str.length - 1) : str; } /** * @description Get the default value of this property * * @return {string} Default value of this property */ DriverProperty.prototype._getDefaultValue = function() { var value; for (var i = 0; i < DEFAULT_REGEX_LIST.length; i++) { var match = this.desc.match(DEFAULT_REGEX_LIST[i]); if (match) { value = trimQuotes(match[1]); break; } } $log.debug("_getDefaultValue | " + this.desc + " | " + value); return value; }; /** * @description Get the input value of this property * * @return {string} the input value of this property */ DriverProperty.prototype.getInputValue = function() { return this.inputValue; }; /** * @description Get the default value of this property * * @return {string} the default value of this property */ DriverProperty.prototype.getDefaultValue = function() { return this.defaultValue; }; /** * @description Get the description of this property * * @return {string} Description of this property */ DriverProperty.prototype.getDescription = function() { return this.desc; }; /** * @description Use the property description to build an expression * that will evaluate to a boolean result indicating whether the * property is active * * @return {array} null if this property is not dependent on any others; * otherwise, * [0] boolean indicating whether if active a value must be * supplied for this property. * [1] an expression that when evaluated will return a boolean * result indicating whether this property is active */ DriverProperty.prototype._analyzeRequiredOnlyDependencies = function() { var re = /(Required|Used) only if ([^ ]+) is set to /g; var match = re.exec(this.desc); if (!match) { return null; } // Build logical expression to describe under what conditions this // property is active var expr = new PostfixExpr(); var numAdds = 0; var i = NOT_INSIDE_MATCH; var j = re.lastIndex; while (j < this.desc.length) { if (i === NOT_INSIDE_MATCH && this.desc.charAt(j) === ".") { break; } if (this.desc.charAt(j) === '"') { if (i === NOT_INSIDE_MATCH) { i = j + 1; } else { expr.addProperty(match[2]); expr.addValue(this.desc.substring(i, j)); expr.addOperator(PostfixExpr.op.EQ); numAdds++; if (numAdds > 1) { expr.addOperator(PostfixExpr.op.OR); } i = NOT_INSIDE_MATCH; } } j++; } $log.debug("_analyzeRequiredOnlyDependencies | " + this.desc + " | " + match[2] + ", " + JSON.stringify(expr)); return [match[1] === "Required", expr]; }; DriverProperty.prototype._analyzeOneOfDependencies = function() { var match = this.desc.match(ONE_OF_REGEX); if (!match) { return null; } // Build logical expression to describe under what conditions this // property is active var expr = new PostfixExpr(); var parts = match[1].split(", or "); expr.addProperty(parts[1]); expr.addValue(undefined); expr.addOperator(PostfixExpr.op.EQ); parts = parts[0].split(", "); for (var i = 0; i < parts.length; i++) { expr.addProperty(parts[i]); expr.addValue(undefined); expr.addOperator(PostfixExpr.op.EQ); expr.addOperator(PostfixExpr.op.AND); } $log.debug("_analyzeOneOfDependencies | " + this.desc + " | " + JSON.stringify(match) + ", " + JSON.stringify(expr)); return [true, expr]; }; /** * @description Get the names of the driver-properties whose values * determine whether this property is active * * @return {object} Object the properties of which are names of * activating driver-properties or null */ DriverProperty.prototype.getActivators = function() { return this.isActiveExpr ? this.isActiveExpr.getProperties() : null; }; /** * PostFixExpr is a class primarily developed to support the * evaluation of boolean expressions that determine whether a * particular property is active. * * The expression is stored as a postfix sequence of operands and * operators. Operands are currently limited to the literal values * and the values of properties in a specified set. Currently * supported operands are ==, or, and. * * @return {void} */ function PostfixExpr() { this.elem = []; } PostfixExpr.op = { EQ: "==", AND: "and", OR: "or" }; PostfixExpr.UNDEFINED = undefined; PostfixExpr.status = { OK: 0, ERROR: 1, BAD_ARG: 2, UNKNOWN_OP: 3, MALFORMED: 4 }; /** * @description Add a property to the expression * * @param {string} propertyName - Property name * * @return {void} */ PostfixExpr.prototype.addProperty = function(propertyName) { this.elem.push({name: propertyName}); }; /** * @description Add a value to the expression * * @param {object} value - value * * @return {void} */ PostfixExpr.prototype.addValue = function(value) { this.elem.push({value: value}); }; /** * @description Add an operator to the expression * * @param {PostfixExpr.op} opId - operator * * @return {void} */ PostfixExpr.prototype.addOperator = function(opId) { this.elem.push({op: opId}); }; /** * @description Get a list of property names referenced by this * expression * * @return {object} An object each property of which corresponds to * a property in the expression */ PostfixExpr.prototype.getProperties = function() { var properties = {}; angular.forEach(this.elem, function(elem) { if (angular.isDefined(elem.name)) { properties[elem.name] = true; } }); return properties; }; /** * @description Evaluate a boolean binary operation * * @param {array} valStack - Stack of values to operate on * @param {string} opId - operator id * * @return {integer} Return code */ function _evaluateBoolBinaryOp(valStack, opId) { var retCode = PostfixExpr.status.OK; var val1 = valStack.pop(); var val2 = valStack.pop(); if (typeof val1 === "boolean" && typeof val2 === "boolean") { switch (opId) { case PostfixExpr.op.AND: valStack.push(val1 && val2); break; case PostfixExpr.op.OR: valStack.push(val1 || val2); break; default: retCode = PostfixExpr.status.UNKNOWN_OP; } } else { retCode = PostfixExpr.status.BAD_ARG; } return retCode; } /** * @description Evaluate the experssion using property values from * a specified set * * @param {object} propertySet - Dictionary of DriverProperty instances * * @return {array} Return code and Value of the expression */ PostfixExpr.prototype.evaluate = function(propertySet) { var resultStack = []; for (var i = 0, len = this.elem.length; i < len; i++) { var elem = this.elem[i]; if (elem.hasOwnProperty("name")) { resultStack.push(propertySet[elem.name].getInputValue()); } else if (elem.hasOwnProperty("value")) { resultStack.push(elem.value); } else if (elem.hasOwnProperty("op")) { if (elem.op === PostfixExpr.op.EQ) { var val1 = resultStack.pop(); var val2 = resultStack.pop(); resultStack.push(val1 === val2); } else { var ret = _evaluateBoolBinaryOp(resultStack, elem.op); if (ret !== PostfixExpr.status.OK) { return [ret, PostfixExpr.UNDEFINED]; } } } else { return [PostfixExpr.status.UNKNOWN_ELEMENT, PostfixExpr.UNDEFINED]; } } return resultStack.length === 1 ? [PostfixExpr.status.OK, resultStack.pop()] : [PostfixExpr.status.MALFORMED, PostfixExpr.UNDEFINED]; }; /** * @description Class for representing and manipulating undirected * graphs * * @property {object} vertices - Associative array of vertex objects * indexed by property name * @return {object} Graph */ function Graph() { this.vertices = {}; } Graph.prototype.getVertex = function(vertexName) { var vertex = null; if (this.vertices.hasOwnProperty(vertexName)) { vertex = this.vertices[vertexName]; } return vertex; }; /** * @description Add a vertex to this graph * * @param {string} name - Vertex name * @param {object} data - Vertex data * @returns {object} - Newly created vertex */ Graph.prototype.addVertex = function(name, data) { var vertex = {name: name, data: data, adjacents: []}; this.vertices[name] = vertex; return vertex; }; /** * @description Add an undirected edge between two vertices * * @param {string} vertexName1 - Name of first vertex * @param {string} vertexName2 - Name of second vertex * @returns {void} */ Graph.prototype.addEdge = function(vertexName1, vertexName2) { this.vertices[vertexName1].adjacents.push(vertexName2); this.vertices[vertexName2].adjacents.push(vertexName1); }; /** * @description Depth-first-search graph traversal utility function * * @param {object} vertex - Root vertex from which traveral will begin. * It is assumed that this vertex has not alreday been visited as part * of this traversal. * @param {object} visited - Associative array. Each named property * corresponds to a vertex with the same name, and has boolean value * indicating whether the vertex has been alreday visited. * @param {object[]} component - Array of vertices that define a strongly * connected component. * @returns {void} */ Graph.prototype._dfsTraverse = function(vertex, visited, component) { var graph = this; visited[vertex.name] = true; component.push(vertex); /* eslint-disable no-unused-vars */ angular.forEach(vertex.adjacents, function(vertexName) { if (!visited[vertexName]) { graph._dfsTraverse(graph.vertices[vertexName], visited, component); } }); /* eslint-enable no-unused-vars */ }; /** * @description Perform a depth-first-search on a specified graph to * find strongly connected components. A user provided function will * be called to process each component. * * @param {function} componentFunc - Function called on each strongly * connected component. Accepts aruments: array of vertex objects, and * user-provided extra data that can be used in processing the component. * @param {object} extra - Extra data that is passed into the component * processing function. * @returns {void} */ Graph.prototype.dfs = function(componentFunc, extra) { var graph = this; var visited = {}; angular.forEach( graph.vertices, function(unused, name) { visited[name] = false; }); angular.forEach(this.vertices, function(vertex, vertexName) { if (!visited[vertexName]) { var component = []; graph._dfsTraverse(vertex, visited, component); componentFunc(component, extra); } }); }; return service; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-node/base-node.spec.js0000664000567000056710000002003413046166232031306 0ustar jenkinsjenkins00000000000000/** * Copyright 2016 Cray 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. */ (function() { "use strict"; describe( 'horizon.dashboard.admin.ironic.base-node.service', function() { var service; beforeEach(module('horizon.dashboard.admin.ironic')); beforeEach(module(function($provide) { $provide.value('$uibModal', jasmine.createSpy()); })); beforeEach(inject(function($injector) { service = $injector.get('horizon.dashboard.admin.ironic.base-node.service'); })); it('defines the service', function() { expect(service).toBeDefined(); }); describe('DriverProperty', function() { it('Base construction', function() { var propertyName = 'propertyName'; var description = ''; var propertySet = []; var property = new service.DriverProperty(propertyName, description, propertySet); expect(property.name).toBe(propertyName); expect(property.desc).toBe(description); expect(property.propertySet).toBe(propertySet); expect(property.getSelectOptions()).toBe(null); expect(property.required).toBe(false); expect(property.defaultValue).toBe(undefined); expect(property.inputValue).toBe(undefined); expect(property.getInputValue()).toBe(undefined); expect(property.isActive()).toBe(true); }); it('Required - ends with', function() { var property = new service.DriverProperty('propertyName', ' Required.', []); expect(property.required).toBe(true); }); it('Not required - missing space', function() { var property = new service.DriverProperty('propertyName', 'Required.', []); expect(property.required).toBe(false); }); it('Not required - missing period', function() { var property = new service.DriverProperty('propertyName', ' Required', []); expect(property.required).toBe(false); }); it('Select options', function() { var property = new service.DriverProperty( 'propertyName', 'One of "foo", bar.', []); expect(property.getSelectOptions()).toEqual(['foo', 'bar']); }); it('Select options - No single quotes', function() { var property = new service.DriverProperty( 'propertyName', "One of 'foo', bar.", []); expect(property.getSelectOptions()).toEqual(["'foo'", 'bar']); }); it('default - is string', function() { var property = new service.DriverProperty( 'propertyName', 'default is "5.1".', []); expect(property._getDefaultValue()).toEqual('5.1'); }); it('default - period processing', function() { var property = new service.DriverProperty( 'propertyName', 'default is 5.1.', []); expect(property._getDefaultValue()).toEqual('5'); }); }); describe('PostfixExpr', function() { it('Base construction', function() { var expr = new service.PostfixExpr(); var ret = expr.evaluate({}); expect(ret[0]).toBe(service.PostfixExpr.status.MALFORMED); expect(ret[1]).toBe(service.PostfixExpr.UNDEFINED); }); function evalBinary(val1, val2, op) { var propertySet = {}; var prop1 = new service.DriverProperty("prop1", "", propertySet); propertySet.prop1 = prop1; var prop2 = new service.DriverProperty("prop2", "", propertySet); propertySet.prop2 = prop2; var expr = new service.PostfixExpr(); expr.addProperty("prop1"); expr.addProperty("prop2"); prop1.inputValue = val1; prop2.inputValue = val2; expr.addOperator(op); return expr.evaluate(propertySet); } it('T and T', function() { var ret = evalBinary(true, true, service.PostfixExpr.op.AND); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('T and F', function() { var ret = evalBinary(true, false, service.PostfixExpr.op.AND); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('F and T', function() { var ret = evalBinary(false, true, service.PostfixExpr.op.AND); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('F and F', function() { var ret = evalBinary(false, false, service.PostfixExpr.op.AND); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('T or T', function() { var ret = evalBinary(true, true, service.PostfixExpr.op.OR); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('T or F', function() { var ret = evalBinary(true, false, service.PostfixExpr.op.OR); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('F or T', function() { var ret = evalBinary(false, true, service.PostfixExpr.op.OR); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('F or F', function() { var ret = evalBinary(false, false, service.PostfixExpr.op.OR); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('T eq T', function() { var ret = evalBinary(true, true, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('T eq F', function() { var ret = evalBinary(true, false, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('F eq T', function() { var ret = evalBinary(false, true, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('F eq F', function() { var ret = evalBinary(false, false, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('1 eq 1', function() { var ret = evalBinary(1, 1, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(true); }); it('1 eq 0', function() { var ret = evalBinary(1, 0, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); it('"1" eq 1', function() { var ret = evalBinary('1', 1, service.PostfixExpr.op.EQ); expect(ret[0]).toBe(service.PostfixExpr.status.OK); expect(ret[1]).toBe(false); }); }); }); })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/base-node/base-node.html0000664000567000056710000002371713046166232030720 0ustar jenkinsjenkins00000000000000 ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/enroll-node/0000775000567000056710000000000013046166505026547 5ustar jenkinsjenkins00000000000000ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/enroll-node/enroll-node.controller.js0000664000567000056710000000527013046166232033506 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; /** * Controller used to enroll a node in the Ironic database */ angular .module('horizon.dashboard.admin.ironic') .controller('EnrollNodeController', EnrollNodeController); EnrollNodeController.$inject = [ '$rootScope', '$controller', '$uibModalInstance', 'horizon.app.core.openstack-service-api.ironic', 'horizon.dashboard.admin.ironic.events', '$log' ]; function EnrollNodeController($rootScope, $controller, $uibModalInstance, ironic, ironicEvents, $log) { var ctrl = this; $controller('BaseNodeController', {ctrl: ctrl, $uibModalInstance: $uibModalInstance}); ctrl.modalTitle = gettext("Enroll Node"); ctrl.submitButtonTitle = ctrl.modalTitle; init(); function init() { ctrl._loadDrivers(); ctrl._getImages(); } ctrl.submit = function() { $log.debug(">> EnrollNodeController.submit()"); angular.forEach(ctrl.driverProperties, function(property, name) { $log.debug(name + ", required = " + property.isRequired() + ", active = " + property.isActive() + ", input-value = " + property.getInputValue() + ", default-value = " + property.getDefaultValue()); if (property.isActive() && property.getInputValue() && property.getInputValue() !== property.getDefaultValue()) { $log.debug("Setting driver property " + name + " to " + property.inputValue); ctrl.node.driver_info[name] = property.inputValue; } }); ironic.createNode(ctrl.node).then( function(response) { $log.info("create node response = " + JSON.stringify(response)); $rootScope.$emit(ironicEvents.ENROLL_NODE_SUCCESS); $uibModalInstance.close(response.data); }); $log.debug("<< EnrollNodeController.submit()"); }; } })(); ironic-ui-2.2.0/ironic_ui/static/dashboard/admin/ironic/enroll-node/enroll-node.service.js0000664000567000056710000000236713046166232032767 0ustar jenkinsjenkins00000000000000/* * Copyright 2016 Cray 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. */ (function() { 'use strict'; angular .module('horizon.dashboard.admin.ironic') .factory('horizon.dashboard.admin.ironic.enroll-node.service', enrollNodeService); enrollNodeService.$inject = [ '$uibModal', 'horizon.dashboard.admin.ironic.basePath' ]; function enrollNodeService($uibModal, basePath) { var service = { enrollNode: enrollNode }; function enrollNode() { var options = { controller: 'EnrollNodeController as ctrl', backdrop: 'static', templateUrl: basePath + '/base-node/base-node.html' }; return $uibModal.open(options).result; } return service; } })(); ironic-ui-2.2.0/package.json0000664000567000056710000000072313046166232017045 0ustar jenkinsjenkins00000000000000{ "name": "ironic-ui", "version": "1.0.0", "description": "Horizon plugin for OpenStack Ironic.", "scripts": { "lint": "eslint ./" }, "repository": { "type": "git", "url": "git://git.openstack.org/openstack/ironic-ui" }, "author": "Openstack ", "license": "Apache-2.0", "devDependencies": { "eslint": "^1.10.3", "eslint-config-openstack": "^1.2.4", "eslint-plugin-angular": "1.0.0" } } ironic-ui-2.2.0/.eslintrc0000664000567000056710000000050013046166232016374 0ustar jenkinsjenkins00000000000000# Enable eslint-plugin-angular plugins: - angular extends: openstack # Set up globals globals: angular: false module: false env: browser: true jasmine: true rules: angular/no-private-call: 0 angular/no-services: - 2 - - $http - $resource - Restangular angular/no-service-method: 0ironic-ui-2.2.0/PKG-INFO0000664000567000056710000001003513046166505015654 0ustar jenkinsjenkins00000000000000Metadata-Version: 1.1 Name: ironic-ui Version: 2.2.0 Summary: Ironic plugin UI for Horizon to allow users to view and manage bare metal nodes, ports and drivers. Home-page: http://docs.openstack.org/developer/ironic-ui Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description: ======================== Team and repository tags ======================== .. image:: http://governance.openstack.org/badges/ironic-ui.svg :target: http://governance.openstack.org/reference/tags/index.html .. Change things from this point on ========= Ironic UI ========= The Ironic UI is a Horizon plugin that will allow users to view and manage bare metal nodes, ports and drivers. * Free software: Apache license * Documentation: http://docs.openstack.org/developer/ironic-ui * Source: http://git.openstack.org/cgit/openstack/ironic-ui * Bugs: http://bugs.launchpad.net/ironic-ui Features -------- * View bare metal nodes * View node details * Apply maintenance and power on/off actions to the nodes Installation Instructions ------------------------- Please note that the following instructions assume that you have an existing installation of the OpenStack Horizon dashboard application. For Horizon installation please see http://docs.openstack.org/developer/horizon/quickstart.html 1. Clone the Ironic UI repository:: git clone https://git.openstack.org/openstack/ironic-ui 2. Change into the root directory of your horizon installation and activate the python virtual environment. Example:: source .venv/bin/activate .. NOTE:: The ``.venv`` folder is preinstalled when horizon is setup with ``./run_tests.sh``. Do not attempt to reinstall the virtual environment. 3. Copy the ``_2200_ironic.py`` file from ``ironic_ui/enabled/_2200_ironic.py`` file to ``horizon/openstack_dashboard/local/enabled`` directory. Example, set as if being executed from the root of the ironic-ui repository:: cp ./ironic_ui/enabled/_2200_ironic.py ../horizon/horizon/openstack_dashboard/local/enabled 4. Change into the ironic-ui repository and package the plugin:: pip install -e . This will build and install the ironic-ui plugin into the active virtual environment associated with your horizon installation. The plugin is installed in "editable" mode as a link back to your ironic-ui plugin directory. Also ensure that all packages as per requirements.txt have been installed. 5. Change back into the horizon repository and bring up your environment:: ./run_tests.sh --runserver The Ironic Bare Metal Provisioning plugin should now be visible in the Horizon navigation. Uninstallation -------------- To uninstall, use ``pip uninstall ironic-ui`` from with-in the horizon virtual environment. You will also need to remove the ``openstack_dashboard/enabled/_2200_ironic.py`` file from the horizon installation. 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 :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 ironic-ui-2.2.0/ChangeLog0000664000567000056710000001052313046166503016331 0ustar jenkinsjenkins00000000000000CHANGES ======= 2.2.0 ----- * Release notes for recently added features * Add support for editing Ironic network ports * Imported Translations from Zanata * Add support for additional port attributes * Fix node validation problem * Imported Translations from Zanata * Remove node-action deleteNodes/deletePorts functions * Improvements to enroll-node service * Improve error handling for the ironic-ui service * Updated from global requirements * Imported Translations from Zanata * Imported Translations from Zanata * Add Python 3.5 classifier and venv * Updated from global requirements * Create base-port module to support create and update operations * Refactor the edit-node/nodeUpdatePatch class * Display current node cleaning step * Add support for aborting node cleaning * Changes required for updated Bootstrap version * Imported Translations from Zanata * Added support for the node introspection workflow * Removes unnecessary utf-8 encoding * Add Constraints support * Extend support for the Ironic state machine * Updated from global requirements * Refactor ironic-ui documentation to remove warnings * Unit tests for PostfixExpr utility class * Consolidate node last_error processing * Imported Translations from Zanata * Show team and repo badges on README * Don't include openstack/common in flake8 exclude list * Incorporate driver-validation into node-detail panels * Imported Translations from Zanata * Fixed bug in representation of ironic state machine * Add a check for node last_error equal to null * Eliminate references to non-existent admin module * Imported Translations from Zanata * Eliminate use of a now obsolete admin basePath variable * Update .coveragerc after the removal of openstack directory * Enable release notes translation * Fix Jasmine unit tests * Fixed processing of node properties with null value * Fixed typo in edit-node service * Consolidate processing of node properties 2.1.0 ----- * Added release notes for 2.1.0 release * Added support for editing Ironic nodes * Update homepage with developer documentation page * Clean imports in code * TrivialFix: Remove logging import unused * Minor state-machine fixes/updates * update homepage with developer documentation page * Updated to ironic API v1.11 and added manageable state * Add translation support * Improve the display of node information * Cleanup tox.ini * Imported Translations from Zanata * Imported Translations from Zanata 2.0.0 ----- * Added release notes for 2.0.0 release * Add reno for release notes management * Hide panel if 'baremetal' service not present * Added support for creating/deleting network ports * Imported Translations from Zanata * Inherit test settings from Horizon * Fix a mistake in the document about the filepath * Changed dropdown menu to align right on driver details page * Imported Translations from Zanata * UX improvements to the enroll-node dialog * Updated ironic-ui documentation * Provide capability to select deploy images * Fixed node-detail controller unit test * Fix node list magic search bar * Imported Translations from Zanata * Fixed bug in evaluation of postfix expression * Manually fixed breadcrumbs for ironic-ui * UI improvements for enroll node functionality * Added functionality to enroll a node, and delete node(s) * Imported Translations from Zanata * Imported Translations from Zanata * Display all properties and instance info * Imported Translations from Zanata * Images uuid giving 404 fix * Remove executable flag from node-list.html * Remove python-ironicclient from setup_requires 1.1.0 ----- * Added closing tag - quick fix * Add support for specifying a maintenance reason * Added eslint config to ironic-ui * Add support for magic-search-bar * Added success messages to power change * Fixing nits of ironic-ui Readme.rst * Fix translation setup * Don't hyperlink images that are specified as URLs * Amended table styling 1.0.0 ----- * Register ironic-ui REST endpoints * Changed naming of Ironic api files * Added node details page to the plugin * Added node list pages to the plugin * Add API services Javascript 0.0.1 ----- * Move index.html to content folder * Reorganise Python according to Horizon plugin doc * Added installation instructions to the Readme * Plugin setup * Translation setup * Corrected copyright details for the project * Amended readme file to be more accurate and readable * Added cookiecutter files * Added .gitreview